package com.aizuda.boot.modules.business.contract.service.impl;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ObjectUtil;
import com.aizuda.boot.modules.business.contract.dto.UserInfo;
import com.aizuda.boot.modules.business.contract.entity.*;
import com.aizuda.boot.modules.business.contract.entity.dto.*;
import com.aizuda.boot.modules.business.contract.entity.vo.*;
import com.aizuda.boot.modules.business.contract.mapper.ContractFieldValueMapper;
import com.aizuda.boot.modules.business.contract.service.*;
import com.aizuda.boot.modules.business.contract.dto.SingleResponse;
import com.aizuda.boot.modules.common.constant.RedisKeyConstant;
import com.aizuda.boot.modules.common.constant.enums.*;
import com.aizuda.boot.modules.business.contract.mapper.ContractFieldMapper;
import com.aizuda.boot.modules.business.contract.mapper.ContractModuleFieldMapper;
import com.aizuda.boot.modules.business.contract.mapper.ContractModuleMapper;
import com.aizuda.boot.modules.business.contract.util.AuthUtil;
import com.aizuda.boot.modules.business.contract.entity.ContractTypeEntity;
import com.aizuda.boot.modules.common.util.RedisService;
import com.aizuda.boot.modules.system.entity.SysDepartment;
import com.aizuda.boot.modules.system.entity.vo.UserAvatarVO;
import com.aizuda.boot.modules.system.mapper.SysUserMapper;
import com.aizuda.boot.modules.system.entity.vo.department.DepartmentTreeVO;
import com.aizuda.boot.modules.system.service.ISysDepartmentService;
import com.aizuda.boot.modules.system.service.ISysUserDepartmentService;
import com.aizuda.bpm.engine.entity.FlwProcess;
import com.aizuda.bpm.mybatisplus.mapper.FlwProcessMapper;
import com.aizuda.core.api.ApiAssert;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * @Author sangyirong
 * @ClassName ContractExe
 * @Version 1.0
 * @Date 2025/5/20 14:46
 */
@Service
@Slf4j
public class ContractExe {

    @Autowired
    private ContractFieldService contractFieldService;

    @Autowired
    private ContractModuleFieldService contractModuleFieldService;

    @Autowired
    private ContractModuleService contractModuleService;

    @Autowired
    private ContractTypeDepartmentService contractTypeDepartmentService;

    @Autowired
    private ContractTypeService contractTypeService;

    @Autowired
    private ContractWorkflowFormFieldService contractWorkflowFormFieldService;

    @Autowired
    private ContractWorkflowService contractWorkflowService;

    @Autowired
    private ContractWorkflowTypeService contractWorkflowTypeService;


    @Resource
    private ContractFieldValueMapper contractFieldValueMapper;

    @Resource
    private ContractWorkflowModuleService contractWorkflowModuleService;

    @Autowired
    private ContractModuleMapper contractModuleMapper;

    @Autowired
    private ContractFieldMapper contractFieldMapper;

    @Autowired
    private ContractModuleFieldMapper contractModuleFieldMapper;
    @Resource
    private WorkflowTypeService workflowTypeService;

    @Resource
    private FlwProcessMapper flwProcessMapper;

    @Resource
    private ISysDepartmentService sysDepartmentService;

    @Resource
    private ContractWorkflowDepartmentService contractWorkflowDepartmentService;

    @Resource
    private ISysUserDepartmentService sysUserDepartmentService;

    @Resource
    private ContractWorkflowLegalService contractWorkflowLegalService;

    @Resource
    private ContractTypeUserService contractTypeUserService;

    @Resource
    private RedisService redisService;
    
    @Resource
    private SysUserMapper sysUserMapper;


    /**
     * 获取合同类型列表
     *
     * @return
     */
    public SingleResponse<List<ContractTypeShowDTO>> listContractTypes() {
        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (Objects.isNull(currentUser.getEmployeeId())) {
            return SingleResponse.failure(ResponseCodeEnum.NOT_LOGGED.getCode(), ResponseCodeEnum.NOT_LOGGED.getMsg());
        }
        // 后续仅按关联部门查询部门名称，避免全量加载

        // 获取所有合同类型数据
        List<ContractTypeEntity> contractTypes = contractTypeService.list();
        if (CollectionUtils.isEmpty(contractTypes)) {
            return SingleResponse.of(new ArrayList<>());
        }

        // 获取合同类型与部门的关联关系
        List<Integer> typeIds = contractTypes.stream().map(ContractTypeEntity::getId).collect(Collectors.toList());
        LambdaQueryWrapper<ContractTypeDepartmentEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(ContractTypeDepartmentEntity::getContractTypeId, typeIds);
        List<ContractTypeDepartmentEntity> typeDepartments = contractTypeDepartmentService.list(wrapper);

        // 构建合同类型与部门的映射关系
        Map<Integer, List<Long>> typeDepartmentMap = typeDepartments.stream()
                .collect(Collectors.groupingBy(
                        ContractTypeDepartmentEntity::getContractTypeId,
                        Collectors.mapping(ContractTypeDepartmentEntity::getDepartmentId, Collectors.toList())
                ));

        // 仅查询关联的部门名称，避免全量部门查询
        Set<Long> associatedDepartmentIds = typeDepartments.stream()
                .map(ContractTypeDepartmentEntity::getDepartmentId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        Map<Long, String> departmentNames = new HashMap<>();
        if (!associatedDepartmentIds.isEmpty()) {
            List<SysDepartment> associatedDepartments = sysDepartmentService.listByIds(associatedDepartmentIds);
            if (associatedDepartments != null) {
                departmentNames = associatedDepartments.stream()
                        .filter(Objects::nonNull)
                        .collect(Collectors.toMap(SysDepartment::getId, SysDepartment::getName));
            }
        }
        long totalDepartmentCount = sysDepartmentService.count();

        // 获取合同类型与用户的关联关系
        LambdaQueryWrapper<ContractTypeUser> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.in(ContractTypeUser::getContractTypeId, typeIds);
        List<ContractTypeUser> typeUsers = contractTypeUserService.list(userWrapper);

        // 构建合同类型与用户的映射关系
        Map<Integer, List<Long>> typeUserMap = typeUsers.stream()
                .collect(Collectors.groupingBy(
                        ContractTypeUser::getContractTypeId,
                        Collectors.mapping(ContractTypeUser::getUserId, Collectors.toList())
                ));

        // 预加载用户头像信息
        Map<Long, UserAvatarVO> userAvatarMap = new HashMap<>();
        if (!typeUsers.isEmpty()) {
            List<Long> userIds = typeUsers.stream()
                    .map(ContractTypeUser::getUserId)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());
            if (!userIds.isEmpty()) {
                List<UserAvatarVO> avatars = sysUserMapper.getUserAvatarsByIds(userIds);
                if (avatars != null) {
                    for (UserAvatarVO avatar : avatars) {
                        if (avatar != null) {
                            userAvatarMap.put(avatar.getUserId(), avatar);
                        }
                    }
                }
            }
        }

        // 筛选一级分类
        List<ContractTypeEntity> firstLevelTypes = contractTypes.stream()
                .filter(type -> type.getParentId() == null)
                .collect(Collectors.toList());

        // 获取一级分类id
        List<Integer> firstLevelIds = firstLevelTypes.stream()
                .map(ContractTypeEntity::getId)
                .collect(Collectors.toList());

        // 根据一级分类获取二级分类
        List<ContractTypeEntity> secondLevelTypes = contractTypes.stream()
                .filter(type -> firstLevelIds.contains(type.getParentId()))
                .collect(Collectors.toList());

        // 获取二级分类的id
        List<Integer> secondLevelIds = secondLevelTypes.stream()
                .map(ContractTypeEntity::getId)
                .collect(Collectors.toList());

        // 获取一级二级映射
        Map<Integer, List<ContractTypeEntity>> firstLevelChildMap = secondLevelTypes.stream()
                .collect(Collectors.groupingBy(ContractTypeEntity::getParentId));

        // 获取二级三级映射
        Map<Integer, List<ContractTypeEntity>> secondLevelChildMap = contractTypes.stream()
                .filter(type -> secondLevelIds.contains(type.getParentId()))
                .collect(Collectors.groupingBy(ContractTypeEntity::getParentId));

        // 构建结果
        ArrayList<ContractTypeShowDTO> contractTypeShowDTOS = new ArrayList<>();
        for (ContractTypeEntity firstLevel : firstLevelTypes) {
            ContractTypeShowDTO firstLevelDTO = getContractTypeDTO(firstLevel, departmentNames, typeDepartmentMap, typeUserMap, userAvatarMap, totalDepartmentCount);
            List<ContractTypeEntity> secondLevel = firstLevelChildMap.getOrDefault(firstLevel.getId(), new ArrayList<>());
            ArrayList<ContractTypeShowDTO> secondLevelDTOS = new ArrayList<>();
            for (ContractTypeEntity second : secondLevel) {
                ContractTypeShowDTO secondLevelDTO = getContractTypeDTO(second, departmentNames, typeDepartmentMap, typeUserMap, userAvatarMap, totalDepartmentCount);
                List<ContractTypeEntity> thirdLevel = secondLevelChildMap.getOrDefault(second.getId(), new ArrayList<>());
                ArrayList<ContractTypeShowDTO> thirdLevelDTOS = new ArrayList<>();
                for (ContractTypeEntity third : thirdLevel) {
                    ContractTypeShowDTO thirdLevelDTO = getContractTypeDTO(third, departmentNames, typeDepartmentMap, typeUserMap, userAvatarMap, totalDepartmentCount);
                    thirdLevelDTOS.add(thirdLevelDTO);
                }
                secondLevelDTO.setChildren(thirdLevelDTOS);
                secondLevelDTOS.add(secondLevelDTO);
            }
            firstLevelDTO.setChildren(secondLevelDTOS);
            contractTypeShowDTOS.add(firstLevelDTO);
        }
        return SingleResponse.of(contractTypeShowDTOS);
    }

    /**
     * 递归获取合同类型树形结构
     * @param contractTypeEntity
     * @param departMap
     * @param typeDepartmentMap
     * @param typeUserMap
     * @param userAvatarMap
     * @return
     */
    private ContractTypeShowDTO getContractTypeDTO(ContractTypeEntity contractTypeEntity,
                                                   Map<Long, String> departMap,
                                                   Map<Integer, List<Long>> typeDepartmentMap,
                                                   Map<Integer, List<Long>> typeUserMap,
                                                   Map<Long, UserAvatarVO> userAvatarMap,
                                                   long allDepartmentCount) {
        ContractTypeShowDTO dto = new ContractTypeShowDTO();
        BeanUtils.copyProperties(contractTypeEntity, dto);

        dto.setApplicableType(contractTypeEntity.getApplicableType());

        // 根据适用类型填充对应数据（互斥展示）
        if (Objects.equals(ContractTypeApplicableType.USER.getKey(), contractTypeEntity.getApplicableType())) {
            List<Long> userIds = typeUserMap.getOrDefault(contractTypeEntity.getId(), new ArrayList<>());
            List<UserAvatarVO> users = userIds.stream()
                    .map(userAvatarMap::get)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
            dto.setApplicableUsers(users);
            // 部门相关置空/默认
            dto.setApplicableDepartments(Collections.emptyList());
            dto.setIsAllDepartment(false);
        } else {
            // 默认按部门处理（向后兼容）
            List<Long> departmentIds = typeDepartmentMap.getOrDefault(contractTypeEntity.getId(), Collections.emptyList());
            List<String> departmentNameList = departmentIds.stream()
                    .map(departMap::get)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
            dto.setApplicableDepartments(departmentNameList);
            dto.setIsAllDepartment(allDepartmentCount > 0 && departmentIds.size() == allDepartmentCount);
            dto.setApplicableUsers(Collections.emptyList());
        }
        return dto;
    }

    // 兼容旧调用签名的方法（仅部门）
    private ContractTypeShowDTO getContractTypeDTO(ContractTypeEntity contractTypeEntity,
                                                   Map<Long, String> departMap,
                                                   Map<Integer, List<Long>> typeDepartmentMap) {
        long allDepartmentCount = sysDepartmentService.count();
        return getContractTypeDTO(contractTypeEntity, departMap, typeDepartmentMap,
                Collections.emptyMap(), Collections.emptyMap(), allDepartmentCount);
    }

    /**
     * 创建合同类型
     *
     * @param contractTypeAddDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse createContractType(ContractTypeAddDTO contractTypeAddDTO) {
        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (Objects.isNull(currentUser.getEmployeeId())) {
            return SingleResponse.failure(ResponseCodeEnum.NOT_LOGGED.getCode(), "用户未登录");
        }
        // 参数校验
        if (Objects.isNull(contractTypeAddDTO)) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同类型数据不能为空");
        }
        if (StringUtils.isEmpty(contractTypeAddDTO.getTypeName())) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同类型名称不能为空");
        }
        // 适用类型互斥校验
        if (!StringUtils.hasText(contractTypeAddDTO.getApplicableType()) ||
                (!Objects.equals(contractTypeAddDTO.getApplicableType(), ContractTypeApplicableType.USER.getKey()) &&
                        !Objects.equals(contractTypeAddDTO.getApplicableType(), ContractTypeApplicableType.DEPARTMENT.getKey()))) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "适用类型必须为 user 或 department");
        }
        if (Objects.equals(contractTypeAddDTO.getApplicableType(), ContractTypeApplicableType.USER.getKey())) {
            if (CollectionUtils.isEmpty(contractTypeAddDTO.getApplicableUsers())) {
                return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "适用用户不能为空");
            }
            if (!CollectionUtils.isEmpty(contractTypeAddDTO.getApplicableDepartments())) {
                return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "适用用户与适用部门只能二选一");
            }
        } else if (Objects.equals(contractTypeAddDTO.getApplicableType(), ContractTypeApplicableType.DEPARTMENT.getKey())) {
            if (CollectionUtils.isEmpty(contractTypeAddDTO.getApplicableDepartments())) {
                return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "适用部门不能为空");
            }
            if (!CollectionUtils.isEmpty(contractTypeAddDTO.getApplicableUsers())) {
                return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "适用用户与适用部门只能二选一");
            }
        }

        // 检查父类型
        Integer parentId = contractTypeAddDTO.getParentId();
        if (parentId != null) {
            // 如果是三级类型，检查父类型是否存在
            ContractTypeEntity parentType = contractTypeService.getById(parentId);
            if (Objects.isNull(parentType)) {
                return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "父合同类型不存在");
            }
            if (parentType.getParentId() != null) {
                ContractTypeEntity fistLevel = contractTypeService.getById(parentType.getParentId());
                if (Objects.isNull(fistLevel)) {
                    return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "父合同类型不存在");
                }
                if (fistLevel.getParentId() != null) {
                    return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "一级类型不能有父类型");
                }
            }
        }

        // 检查类型名称是否重复
        long count = contractTypeService.count(new LambdaQueryWrapper<ContractTypeEntity>()
                .eq(ContractTypeEntity::getTypeAbbreviation, contractTypeAddDTO.getTypeAbbreviation()));
        if (count > 0) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同类型重复");
        }

        // 获取当前层级的最大排序号
        LambdaQueryWrapper<ContractTypeEntity> sortWrapper = new LambdaQueryWrapper<>();
        if (parentId != null) {
            // 二级三级类型：获取同一父类型下的最大排序号
            sortWrapper.eq(ContractTypeEntity::getParentId, parentId);
        } else {
            // 一级类型：获取所有一级类型的最大排序号
            sortWrapper.isNull(ContractTypeEntity::getParentId);
        }
        sortWrapper.orderByDesc(ContractTypeEntity::getTypeOrder).last("LIMIT 1");
        ContractTypeEntity maxOrderType = contractTypeService.getOne(sortWrapper);
        Integer typeOrder = maxOrderType != null ? maxOrderType.getTypeOrder() + 1 : 1;

        // 创建合同类型
        ContractTypeEntity contractTypeEntity = new ContractTypeEntity();
        BeanUtils.copyProperties(contractTypeAddDTO, contractTypeEntity);
        contractTypeEntity.setIsEnabled(true); // 默认启用
        contractTypeEntity.setTypeOrder(typeOrder); // 设置排序号
        contractTypeService.save(contractTypeEntity);

        if (ContractTypeApplicableType.USER.getKey().equals(contractTypeAddDTO.getApplicableType())){
            if (!CollectionUtils.isEmpty(contractTypeAddDTO.getApplicableUsers())){
                List<ContractTypeUser> typeUsers = contractTypeAddDTO.getApplicableUsers().stream()
                        .map(userId -> {
                            ContractTypeUser typeUser = new ContractTypeUser();
                            typeUser.setContractTypeId(contractTypeEntity.getId());
                            typeUser.setUserId(userId);
                            return typeUser;
                        })
                        .collect(Collectors.toList());
                contractTypeUserService.saveBatch(typeUsers);
            }
        }
        if (ContractTypeApplicableType.DEPARTMENT.getKey().equals(contractTypeAddDTO.getApplicableType())){
            // 处理部门关联
            if (!CollectionUtils.isEmpty(contractTypeAddDTO.getApplicableDepartments())) {
                List<ContractTypeDepartmentEntity> typeDepartments = contractTypeAddDTO.getApplicableDepartments().stream()
                        .map(departmentId -> {
                            ContractTypeDepartmentEntity typeDepartment = new ContractTypeDepartmentEntity();
                            typeDepartment.setContractTypeId(contractTypeEntity.getId());
                            typeDepartment.setDepartmentId(departmentId);
                            return typeDepartment;
                        })
                        .collect(Collectors.toList());
                contractTypeDepartmentService.saveBatch(typeDepartments);
            }
        }


        // 创建成功，更新缓存
        ContractTypeCache contractTypeCache = new ContractTypeCache();
        BeanUtils.copyProperties(contractTypeEntity, contractTypeCache);
        if (Objects.equals(contractTypeAddDTO.getApplicableType(), ContractTypeApplicableType.DEPARTMENT.getKey())) {
            contractTypeCache.setDepartmentIds(contractTypeAddDTO.getApplicableDepartments());
        } else {
            contractTypeCache.setDepartmentIds(Collections.emptyList());
        }
        redisService.setHashObject(RedisKeyConstant.Business.CONTRACT_TYPE_PREFIX + contractTypeEntity.getId(), contractTypeCache);
        return SingleResponse.success();
    }

    /**
     * 获取合同类型详情
     *
     * @param id
     * @return
     */
    public SingleResponse<ContractTypeDetailShowDTO> getContractType(Integer id) {
        // 参数校验
        if (Objects.isNull(id)) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同类型ID不能为空");
        }

        // 获取合同类型信息
        ContractTypeEntity contractTypeEntity = contractTypeService.getById(id);
        if (Objects.isNull(contractTypeEntity)) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同类型不存在");
        }

        // 构建返回对象
        ContractTypeDetailShowDTO detailDTO = new ContractTypeDetailShowDTO();
        BeanUtils.copyProperties(contractTypeEntity, detailDTO);
        detailDTO.setApplicableType(contractTypeEntity.getApplicableType());

        // 根据适用类型返回互斥数据（不做不适用部门）
        if (Objects.equals(ContractTypeApplicableType.USER.getKey(), contractTypeEntity.getApplicableType())) {
            LambdaQueryWrapper<ContractTypeUser> userWrapper = new LambdaQueryWrapper<>();
            userWrapper.eq(ContractTypeUser::getContractTypeId, id);
            List<ContractTypeUser> typeUsers = contractTypeUserService.list(userWrapper);

            List<Long> userIds = typeUsers.stream()
                    .map(ContractTypeUser::getUserId)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());
            List<UserAvatarVO> users = userIds.isEmpty() ? Collections.emptyList() : sysUserMapper.getUserAvatarsByIds(userIds);
            detailDTO.setApplicableUsers(users);

            // 适用用户时，部门信息为空
            detailDTO.setApplicableDepartments(Collections.emptyList());
            detailDTO.setIsAllDepartment(false);
        } else {
            // 默认按部门处理（向后兼容）
            Map<Long, String> departmentNames = sysDepartmentService.getAllDepartmentNames();
            if (Objects.isNull(departmentNames)) {
                return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "获取所有部门数据失败");
            }
            int departmentCount = departmentNames.size();

            LambdaQueryWrapper<ContractTypeDepartmentEntity> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ContractTypeDepartmentEntity::getContractTypeId, id);
            List<ContractTypeDepartmentEntity> typeDepartments = contractTypeDepartmentService.list(wrapper);

            List<Long> departmentIds = typeDepartments.stream()
                    .map(ContractTypeDepartmentEntity::getDepartmentId)
                    .collect(Collectors.toList());

            List<ContractTypeDetailShowDTO.DepartmentInfo> applicableDepartmentInfos = departmentIds.stream()
                    .map(departmentId -> {
                        String departmentName = departmentNames.get(departmentId);
                        return new ContractTypeDetailShowDTO.DepartmentInfo(departmentId, departmentName != null ? departmentName : "未知部门");
                    })
                    .collect(Collectors.toList());

            detailDTO.setApplicableDepartments(applicableDepartmentInfos);
            detailDTO.setIsAllDepartment(departmentIds.size() == departmentCount);

            // 不做不适用部门
            detailDTO.setNonApplicableDepartments(Collections.emptyList());
            detailDTO.setApplicableUsers(Collections.emptyList());
        }

        // 如果是二级类型，设置父类型信息
        if (contractTypeEntity.getParentId() != null) {
            ContractTypeEntity parentType = contractTypeService.getById(contractTypeEntity.getParentId());
            if (parentType != null) {
                detailDTO.setParentTypeName(parentType.getTypeName());
            }
        }

        return SingleResponse.of(detailDTO);
    }

    /**
     * 编辑合同类型
     *
     * @param id
     * @param contractTypeUpdateDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse updateContractType(Integer id, ContractTypeUpdateDTO contractTypeUpdateDTO) {
        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (Objects.isNull(currentUser.getEmployeeId())) {
            return SingleResponse.failure(ResponseCodeEnum.NOT_LOGGED.getCode(), ResponseCodeEnum.NOT_LOGGED.getMsg());
        }
        // 参数校验
        if (Objects.isNull(id)) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同类型ID不能为空");
        }
        if (Objects.isNull(contractTypeUpdateDTO)) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同类型数据不能为空");
        }
        if (!id.equals(contractTypeUpdateDTO.getId())) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同类型ID和合同类型数据ID不一致");
        }
        if (!StringUtils.hasText(contractTypeUpdateDTO.getTypeName())) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同类型名称不能为空");
        }
        // 适用类型互斥校验
        if (!StringUtils.hasText(contractTypeUpdateDTO.getApplicableType()) ||
                (!Objects.equals(contractTypeUpdateDTO.getApplicableType(), ContractTypeApplicableType.USER.getKey()) &&
                        !Objects.equals(contractTypeUpdateDTO.getApplicableType(), ContractTypeApplicableType.DEPARTMENT.getKey()))) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "适用类型必须为 user 或 department");
        }
        if (Objects.equals(contractTypeUpdateDTO.getApplicableType(), ContractTypeApplicableType.USER.getKey())) {
            if (CollectionUtils.isEmpty(contractTypeUpdateDTO.getApplicableUsers())) {
                return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "适用用户不能为空");
            }
            if (!CollectionUtils.isEmpty(contractTypeUpdateDTO.getApplicableDepartments())) {
                return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "适用用户与适用部门只能二选一");
            }
        } else if (Objects.equals(contractTypeUpdateDTO.getApplicableType(), ContractTypeApplicableType.DEPARTMENT.getKey())) {
            if (CollectionUtils.isEmpty(contractTypeUpdateDTO.getApplicableDepartments())) {
                return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "适用部门不能为空");
            }
            if (!CollectionUtils.isEmpty(contractTypeUpdateDTO.getApplicableUsers())) {
                return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "适用用户与适用部门只能二选一");
            }
        }

        // 获取原合同类型信息
        ContractTypeEntity existingType = contractTypeService.getById(id);
        if (Objects.isNull(existingType)) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同类型不存在");
        }

        // 检查父类型
        Integer parentId = contractTypeUpdateDTO.getParentId();
        if (parentId != null) {
            // 如果是二级类型，检查父类型是否存在且是一级类型
            ContractTypeEntity parentType = contractTypeService.getById(parentId);
            if (Objects.isNull(parentType)) {
                return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "父合同类型不存在");
            }
            if (parentType.getParentId() != null) {
                ContractTypeEntity firstLevel = contractTypeService.getById(parentType.getParentId());
                if (Objects.isNull(firstLevel)) {
                    return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "父合同类型不存在");
                }
                if (firstLevel.getParentId() != null) {
                    return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "父类型错误");
                }

            }
        }

        // 检查类型编号是否重复（排除自身）
        long count = contractTypeService.count(new LambdaQueryWrapper<ContractTypeEntity>()
                .eq(ContractTypeEntity::getTypeAbbreviation, contractTypeUpdateDTO.getTypeAbbreviation())
                .ne(ContractTypeEntity::getId, id));
        if (count > 0) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同类型重复");
        }

        // 删除缓存，避免缓存数据不一致
        redisService.deleteObject(RedisKeyConstant.Business.CONTRACT_TYPE_PREFIX + id);

        // 更新合同类型基本信息
        ContractTypeEntity contractTypeEntity = new ContractTypeEntity();
        BeanUtils.copyProperties(contractTypeUpdateDTO, contractTypeEntity);
        contractTypeEntity.setId(id);
        // 保持原有的排序字段不变
        contractTypeEntity.setTypeOrder(existingType.getTypeOrder());
        contractTypeService.updateById(contractTypeEntity);

        // 更新关联关系（部门或用户二选一）
        if (Objects.equals(contractTypeUpdateDTO.getApplicableType(), ContractTypeApplicableType.DEPARTMENT.getKey())) {
            // 清理用户关联
            LambdaQueryWrapper<ContractTypeUser> clearUserWrapper = new LambdaQueryWrapper<>();
            clearUserWrapper.eq(ContractTypeUser::getContractTypeId, id);
            contractTypeUserService.remove(clearUserWrapper);

            // 先删除原有的部门关联
            LambdaQueryWrapper<ContractTypeDepartmentEntity> deleteWrapper = new LambdaQueryWrapper<>();
            deleteWrapper.eq(ContractTypeDepartmentEntity::getContractTypeId, id);
            contractTypeDepartmentService.remove(deleteWrapper);

            // 添加新的部门关联
            if (!CollectionUtils.isEmpty(contractTypeUpdateDTO.getApplicableDepartments())) {
                List<ContractTypeDepartmentEntity> typeDepartments = contractTypeUpdateDTO.getApplicableDepartments().stream()
                        .map(departmentId -> {
                            ContractTypeDepartmentEntity typeDepartment = new ContractTypeDepartmentEntity();
                            typeDepartment.setContractTypeId(id);
                            typeDepartment.setDepartmentId(departmentId);
                            return typeDepartment;
                        })
                        .collect(Collectors.toList());
                contractTypeDepartmentService.saveBatch(typeDepartments);
            }
        } else {
            // 清理部门关联
            LambdaQueryWrapper<ContractTypeDepartmentEntity> deleteWrapper = new LambdaQueryWrapper<>();
            deleteWrapper.eq(ContractTypeDepartmentEntity::getContractTypeId, id);
            contractTypeDepartmentService.remove(deleteWrapper);

            // 清理原有用户关联并添加新的
            LambdaQueryWrapper<ContractTypeUser> clearUserWrapper = new LambdaQueryWrapper<>();
            clearUserWrapper.eq(ContractTypeUser::getContractTypeId, id);
            contractTypeUserService.remove(clearUserWrapper);

            if (!CollectionUtils.isEmpty(contractTypeUpdateDTO.getApplicableUsers())) {
                List<ContractTypeUser> typeUsers = contractTypeUpdateDTO.getApplicableUsers().stream()
                        .map(userId -> {
                            ContractTypeUser typeUser = new ContractTypeUser();
                            typeUser.setContractTypeId(id);
                            typeUser.setUserId(userId);
                            return typeUser;
                        })
                        .collect(Collectors.toList());
                contractTypeUserService.saveBatch(typeUsers);
            }
        }
        ThreadUtil.execute(new Runnable() {
            @Override
            public void run() {
                // 修改成功更新缓存
                try {
                    Thread.sleep(30);
                } catch (Exception e) {
                    log.error("更新合同类型缓存失败", e);
                }
                ContractTypeCache contractTypeCache = new ContractTypeCache();
                BeanUtils.copyProperties(contractTypeEntity, contractTypeCache);
                if (Objects.equals(contractTypeUpdateDTO.getApplicableType(), ContractTypeApplicableType.DEPARTMENT.getKey())) {
                    contractTypeCache.setDepartmentIds(contractTypeUpdateDTO.getApplicableDepartments());
                } else {
                    contractTypeCache.setDepartmentIds(Collections.emptyList());
                }
                redisService.setHashObject(RedisKeyConstant.Business.CONTRACT_TYPE_PREFIX + id, contractTypeCache);
                log.info("更新合同类型缓存成功");
            }
        });

        return SingleResponse.success();
    }

    /**
     * 启用/禁用合同类型
     *
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse toggleContractTypeStatus(Integer id) {
        // 参数校验
        if (id == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同类型ID不能为空");
        }

        // 获取合同类型信息
        ContractTypeEntity contractTypeEntity = contractTypeService.getById(id);
        if (contractTypeEntity == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同类型不存在");
        }

        // 检查父类型状态（适用于二级和三级类型）
        if (contractTypeEntity.getParentId() != null) {
            ContractTypeEntity parentType = contractTypeService.getById(contractTypeEntity.getParentId());
            if (parentType == null) {
                return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "父合同类型不存在");
            }
            if (!parentType.getIsEnabled()) {
                return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "父合同类型已禁用，无法启用子类型");
            }

            // 如果是三级类型，还需要检查二级父类型的状态
            if (parentType.getParentId() != null) {
                ContractTypeEntity grandParentType = contractTypeService.getById(parentType.getParentId());
                if (grandParentType == null) {
                    return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "二级父合同类型不存在");
                }
                if (!grandParentType.getIsEnabled()) {
                    return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "二级父合同类型已禁用，无法启用子类型");
                }
            }
        }

        // 如果是启用状态，检查是否有启用的子类型
        if (contractTypeEntity.getIsEnabled()) {
            LambdaQueryWrapper<ContractTypeEntity> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ContractTypeEntity::getParentId, id)
                    .eq(ContractTypeEntity::getIsEnabled, true);
            Long enabledChildCount = contractTypeService.count(wrapper);
            if (enabledChildCount > 0) {
                return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "存在启用的子类型，无法禁用");
            }
        }

        // 删除缓存，避免缓存数据不一致
        // 更新状态
        contractTypeEntity.setIsEnabled(!contractTypeEntity.getIsEnabled());
        boolean is = contractTypeService.updateById(contractTypeEntity);
        if (is) {
            redisService.setCacheMapValue(RedisKeyConstant.Business.CONTRACT_TYPE_PREFIX + id, RedisCacheEnum.ContractTypeCache.IS_ENABLED.getValue(), contractTypeEntity.getIsEnabled());
        } else {
            log.error("更新合同类型状态失败，请联系管理员");
        }
        return SingleResponse.success();
    }

    /**
     * 删除合同类型
     *
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse deleteContractType(Integer id) {
        // 参数校验
        if (Objects.isNull(id)) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同类型ID不能为空");
        }

        // 获取合同类型信息
        ContractTypeEntity contractTypeEntity = contractTypeService.getById(id);
        if (Objects.isNull(contractTypeEntity)) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同类型不存在");
        }

        // 检查是否有子类型
        LambdaQueryWrapper<ContractTypeEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ContractTypeEntity::getParentId, id);
        Long childCount = contractTypeService.count(wrapper);
        if (childCount > 0) {
            return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "存在子类型，无法删除");
        }

        // 获取当前类型的排序号
        Integer currentOrder = contractTypeEntity.getTypeOrder();
        // todo 其他引用校验

        Long count = contractFieldValueMapper.selectCount(Wrappers.<ContractFieldValueEntity>lambdaQuery()
                .eq(ContractFieldValueEntity::getFieldCode, SystemFieldsEnum.CONTRACT_TYPE.getCode())
                .eq(ContractFieldValueEntity::getFieldValue, id));
        if (count > 0) {
            ApiAssert.fail("合同类型已被关联，不允许删除！");
        }

        if (ContractTypeApplicableType.DEPARTMENT.getKey().equals(contractTypeEntity.getApplicableType())) {
            // 删除部门关联关系
            LambdaQueryWrapper<ContractTypeDepartmentEntity> departmentWrapper = new LambdaQueryWrapper<>();
            departmentWrapper.eq(ContractTypeDepartmentEntity::getContractTypeId, id);
            contractTypeDepartmentService.remove(departmentWrapper);
        }
        if (ContractTypeApplicableType.USER.getKey().equals(contractTypeEntity.getApplicableType())) {
            // 删除用户关联关系
            LambdaQueryWrapper<ContractTypeUser> userWrapper = new LambdaQueryWrapper<>();
            userWrapper.eq(ContractTypeUser::getContractTypeId, id);
            contractTypeUserService.remove(userWrapper);
        }


        // 删除合同类型
        contractTypeService.removeById(id);

        // 删除合同类型缓存
        redisService.deleteObject(RedisKeyConstant.Business.CONTRACT_TYPE_PREFIX + id);

        // 维护排序号
        LambdaQueryWrapper<ContractTypeEntity> orderWrapper = new LambdaQueryWrapper<>();
        if (contractTypeEntity.getParentId() == null) {
            // 一级类型：维护所有一级类型的顺序
            orderWrapper.isNull(ContractTypeEntity::getParentId)
                    .gt(ContractTypeEntity::getTypeOrder, currentOrder);
        } else {
            // 检查父类型是否存在
            ContractTypeEntity parentType = contractTypeService.getById(contractTypeEntity.getParentId());
            if (parentType != null) {
                orderWrapper.eq(ContractTypeEntity::getParentId, contractTypeEntity.getParentId())
                        .gt(ContractTypeEntity::getTypeOrder, currentOrder);
            } else {
                return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "父合同类型不存在");
            }
        }

        // 获取需要更新排序的类型
        List<ContractTypeEntity> typesToUpdate = contractTypeService.list(orderWrapper);
        if (!CollectionUtils.isEmpty(typesToUpdate)) {
            // 更新排序号
            typesToUpdate.forEach(type -> {
                type.setTypeOrder(type.getTypeOrder() - 1);
            });
            contractTypeService.updateBatchById(typesToUpdate);
        }
        return SingleResponse.success();
    }

    /**
     * 合同类型排序
     *
     * @param contractTypeSortDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse sortContractTypes(ContractTypeSortDTO contractTypeSortDTO) {
        // 参数校验
        if (contractTypeSortDTO == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "排序数据不能为空");
        }
        if (contractTypeSortDTO.getId() == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同类型ID不能为空");
        }
        if (contractTypeSortDTO.getSort() == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "排序值不能为空");
        }

        // 获取合同类型信息
        ContractTypeEntity contractTypeEntity = contractTypeService.getById(contractTypeSortDTO.getId());
        if (contractTypeEntity == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同类型不存在");
        }

        // 获取当前排序值
        Integer currentSort = contractTypeEntity.getTypeOrder();
        Integer newSort = contractTypeSortDTO.getSort();

        // 构建查询条件
        LambdaQueryWrapper<ContractTypeEntity> wrapper = new LambdaQueryWrapper<>();

        if (contractTypeEntity.getParentId() == null) {
            // 一级类型排序
            wrapper.isNull(ContractTypeEntity::getParentId);
        } else {
            // 检查父类型是否存在
            ContractTypeEntity parentType = contractTypeService.getById(contractTypeEntity.getParentId());
            if (parentType == null) {
                return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "父合同类型不存在");
            }

            wrapper.eq(ContractTypeEntity::getParentId, contractTypeEntity.getParentId());
        }

        if (currentSort < newSort) {
            // 向后移动：将中间的类型排序值减1
            wrapper.gt(ContractTypeEntity::getTypeOrder, currentSort)
                    .le(ContractTypeEntity::getTypeOrder, newSort);
            List<ContractTypeEntity> updateList = contractTypeService.list(wrapper);
            for (ContractTypeEntity type : updateList) {
                type.setTypeOrder(type.getTypeOrder() - 1);
            }
            contractTypeService.updateBatchById(updateList);
        } else if (currentSort > newSort) {
            // 向前移动：将中间的类型排序值加1
            wrapper.ge(ContractTypeEntity::getTypeOrder, newSort)
                    .lt(ContractTypeEntity::getTypeOrder, currentSort);
            List<ContractTypeEntity> updateList = contractTypeService.list(wrapper);
            for (ContractTypeEntity type : updateList) {
                type.setTypeOrder(type.getTypeOrder() + 1);
            }
            contractTypeService.updateBatchById(updateList);
        }

        // 更新当前类型的排序值
        ContractTypeEntity updateType = new ContractTypeEntity();
        updateType.setId(contractTypeSortDTO.getId());
        updateType.setTypeOrder(newSort);
        contractTypeService.updateById(updateType);

        return SingleResponse.success();
    }

    /**
     * 获取合同模块列表
     *
     * @return
     */
    public SingleResponse<List<ContractModelShowDTO>> listContractModules() {
        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (Objects.isNull(currentUser.getEmployeeId())) {
            return SingleResponse.failure(ResponseCodeEnum.NOT_LOGGED.getCode(), ResponseCodeEnum.NOT_LOGGED.getMsg());
        }
        // 获取所有启用的模块并按排序号排序
        List<ContractModuleEntity> list = contractModuleService.list(new LambdaQueryWrapper<ContractModuleEntity>()
                .eq(ContractModuleEntity::getIsEnabled, true)
                .orderByAsc(ContractModuleEntity::getModuleOrder));

        if (CollectionUtils.isEmpty(list)) {
            return SingleResponse.of(new ArrayList<>());
        }

        List<ContractModelShowDTO> listDTO = list.stream()
                .map(item -> {
                    ContractModelShowDTO contractModelShowDTO = new ContractModelShowDTO();
                    BeanUtils.copyProperties(item, contractModelShowDTO);
                    return contractModelShowDTO;
                }).collect(Collectors.toList());
        return SingleResponse.of(listDTO);
    }

    /**
     * 新增合同模块
     *
     * @param contractModelAddDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse createContractModule(ContractModelAddDTO contractModelAddDTO) {
        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (Objects.isNull(currentUser.getEmployeeId())) {
            return SingleResponse.failure(ResponseCodeEnum.NOT_LOGGED.getCode(), ResponseCodeEnum.NOT_LOGGED.getMsg());
        }
        // 参数校验
        if (contractModelAddDTO == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同模块数据不能为空");
        }
        if (StringUtils.isEmpty(contractModelAddDTO.getModuleName())) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同模块名称不能为空");
        }

        // 检查模块名称是否重复
        LambdaQueryWrapper<ContractModuleEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ContractModuleEntity::getModuleName, contractModelAddDTO.getModuleName());
        Long count = contractModuleService.count(wrapper);
        if (count > 0) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_ALREADY_EXISTS.getCode(), "合同模块名称已存在");
        }

        // 获取当前最大排序号
        ContractModuleEntity maxOrderModule = contractModuleService.getOne(new LambdaQueryWrapper<ContractModuleEntity>()
                .orderByDesc(ContractModuleEntity::getModuleOrder)
                .last("LIMIT 1"));
        Integer moduleOrder = maxOrderModule != null ? maxOrderModule.getModuleOrder() + 1 : 1;

        // 创建合同模块
        ContractModuleEntity contractModuleEntity = new ContractModuleEntity();
        BeanUtils.copyProperties(contractModelAddDTO, contractModuleEntity);
        contractModuleEntity.setModuleOrder(moduleOrder);
        if (contractModelAddDTO.getIsEnabled() == null) {
            contractModuleEntity.setIsEnabled(true);
        }
        contractModuleService.save(contractModuleEntity);

        return SingleResponse.success();
    }

    /**
     * 获取合同模块详情
     *
     * @param id
     * @return
     */
    public SingleResponse<ContractModelDetailShowDTO> getContractModuleById(Integer id) {
        // 参数校验
        if (id == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同模块ID不能为空");
        }

        // 获取合同模块信息
        ContractModuleEntity contractModuleEntity = contractModuleService.getById(id);
        if (contractModuleEntity == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同模块不存在");
        }
        if (!contractModuleEntity.getIsEnabled()) {
            return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "合同模块已禁用");
        }

        // 构建返回对象
        ContractModelDetailShowDTO contractModelDetailShowDTO = new ContractModelDetailShowDTO();
        BeanUtils.copyProperties(contractModuleEntity, contractModelDetailShowDTO);
        return SingleResponse.of(contractModelDetailShowDTO);
    }

    /**
     * 修改合同模块
     *
     * @param id
     * @param contractModelUpdateDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse updateContractModule(Integer id, ContractModelUpdateDTO contractModelUpdateDTO) {
        // 参数校验
        if (id == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同模块ID不能为空");
        }
        if (contractModelUpdateDTO == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同模块数据不能为空");
        }
        if (StringUtils.isEmpty(contractModelUpdateDTO.getModuleName())) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同模块名称不能为空");
        }
        if (!id.equals(contractModelUpdateDTO.getId())) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同模块ID不匹配");
        }

        // 获取原合同模块信息
        ContractModuleEntity existingModule = contractModuleService.getById(id);
        if (existingModule == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同模块不存在");
        }

        // 检查模块名称是否重复（排除自身）
        LambdaQueryWrapper<ContractModuleEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ContractModuleEntity::getModuleName, contractModelUpdateDTO.getModuleName())
                .ne(ContractModuleEntity::getId, id);
        Long count = contractModuleService.count(wrapper);
        if (count > 0) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_ALREADY_EXISTS.getCode(), "合同模块名称已存在");
        }

        // 更新合同模块
        ContractModuleEntity contractModuleEntity = new ContractModuleEntity();
        BeanUtils.copyProperties(contractModelUpdateDTO, contractModuleEntity);
        // 保持原有的排序字段不变
        contractModuleEntity.setModuleOrder(existingModule.getModuleOrder());
        contractModuleService.updateById(contractModuleEntity);

        return SingleResponse.success();
    }

    /**
     * 删除合同模块
     *
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse deleteContractModule(Integer id) {
        // 参数校验
        if (id == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同模块ID不能为空");
        }

        // 获取合同模块信息
        ContractModuleEntity contractModuleEntity = contractModuleService.getById(id);
        if (contractModuleEntity == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同模块不存在");
        }

        if (contractModuleEntity.getIsSystem()) {
            return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "系统合同模块无法删除");
        }

        // 检查是否有关联的合同字段
        LambdaQueryWrapper<ContractModuleFieldEntity> fieldWrapper = new LambdaQueryWrapper<>();
        fieldWrapper.eq(ContractModuleFieldEntity::getModuleId, id).select(ContractModuleFieldEntity::getFieldId);
        List<Long> fieldIds = contractModuleFieldService.list(fieldWrapper).stream()
                .map(ContractModuleFieldEntity::getFieldId)
                .collect(Collectors.toList());

        // 判断是否有字段关联
        if (!CollectionUtils.isEmpty(fieldIds)) {
            LambdaQueryWrapper<ContractWorkflowFormFieldEntity> formFieldWrapper = new LambdaQueryWrapper<>();
            formFieldWrapper.in(ContractWorkflowFormFieldEntity::getFieldId, fieldIds);
            Long formFieldCount = contractWorkflowFormFieldService.count(formFieldWrapper);
            if (formFieldCount > 0) {
                return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "存在关联的工作流表单字段，无法删除");
            }
        }

        // 检查是否有关联的工作流表单字段

        // 删除合同模块
        contractModuleService.removeById(id);
        // 删除合同模块字段
        contractModuleFieldService.remove(new LambdaQueryWrapper<ContractModuleFieldEntity>().eq(ContractModuleFieldEntity::getModuleId, id));

        // 维护其他模块的排序号
        List<ContractModuleEntity> updateList = contractModuleService.list(new LambdaQueryWrapper<ContractModuleEntity>()
                .gt(ContractModuleEntity::getModuleOrder, contractModuleEntity.getModuleOrder()));
        if (!CollectionUtils.isEmpty(updateList)) {
            updateList.forEach(module -> module.setModuleOrder(module.getModuleOrder() - 1));
            contractModuleService.updateBatchById(updateList);
        }

        return SingleResponse.success();
    }

    /**
     * 合同模块排序
     *
     * @param contractModelSortDTO
     * @return
     */
    public SingleResponse sortContractModules(ContractModelSortDTO contractModelSortDTO) {
        // 参数校验
        if (contractModelSortDTO == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "排序数据不能为空");
        }
        if (contractModelSortDTO.getId() == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同模块ID不能为空");
        }
        if (contractModelSortDTO.getSort() == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "排序值不能为空");
        }

        // 获取合同模块信息
        ContractModuleEntity contractModuleEntity = contractModuleService.getById(contractModelSortDTO.getId());
        if (contractModuleEntity == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同模块不存在");
        }

        // 获取当前排序值
        Integer currentSort = contractModuleEntity.getModuleOrder();
        Integer newSort = contractModelSortDTO.getSort();

        // 构建查询条件
        LambdaQueryWrapper<ContractModuleEntity> wrapper = new LambdaQueryWrapper<>();

        if (currentSort < newSort) {
            // 向后移动：将中间的类型排序值减1
            wrapper.gt(ContractModuleEntity::getModuleOrder, currentSort)
                    .le(ContractModuleEntity::getModuleOrder, newSort);
            List<ContractModuleEntity> updateList = contractModuleService.list(wrapper);
            for (ContractModuleEntity module : updateList) {
                module.setModuleOrder(module.getModuleOrder() - 1);
            }
            contractModuleService.updateBatchById(updateList);
        } else if (currentSort > newSort) {
            // 向前移动：将中间的类型排序值加1
            wrapper.ge(ContractModuleEntity::getModuleOrder, newSort)
                    .lt(ContractModuleEntity::getModuleOrder, currentSort);
            List<ContractModuleEntity> updateList = contractModuleService.list(wrapper);
            for (ContractModuleEntity module : updateList) {
                module.setModuleOrder(module.getModuleOrder() + 1);
            }
            contractModuleService.updateBatchById(updateList);
        }

        // 更新当前模块的排序值
        ContractModuleEntity updateModule = new ContractModuleEntity();
        updateModule.setId(contractModelSortDTO.getId());
        updateModule.setModuleOrder(newSort);
        contractModuleService.updateById(updateModule);

        return SingleResponse.success();
    }

    /**
     * 获取合同字段列表
     *
     * @param moduleId
     * @return
     */
    public SingleResponse<List<ContractFieldShowDTO>> listContractFields(Integer moduleId) {
        // 参数校验
        if (moduleId == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同模块ID不能为空");
        }
//        List<ContractFieldShowDTO> cache = redisService.getCacheList(RedisKeyConstant.Business.CONTRACT_MODULE_PREFIX + moduleId);
//        if (!CollectionUtils.isEmpty(cache)) {
//            return SingleResponse.of(cache);
//        }

        // 获取合同模块信息
        ContractModuleEntity contractModuleEntity = contractModuleService.getById(moduleId);
        if (contractModuleEntity == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同模块不存在");
        }
        if (!contractModuleEntity.getIsEnabled()) {
            return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "合同模块已禁用");
        }

        // 获取模块下的所有字段
        LambdaQueryWrapper<ContractModuleFieldEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ContractModuleFieldEntity::getModuleId, moduleId);
        List<ContractModuleFieldEntity> moduleFields = contractModuleFieldService.list(wrapper);

        if (CollectionUtils.isEmpty(moduleFields)) {
            return SingleResponse.of(new ArrayList<>());
        }

        // 获取所有字段ID
        List<Long> fieldIds = moduleFields.stream()
                .map(ContractModuleFieldEntity::getFieldId)
                .collect(Collectors.toList());

        // 获取字段详细信息
        List<ContractFieldEntity> fields = contractFieldService.listByIds(fieldIds).stream()
                .filter(field -> field.getIsEnabled())
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(fields)) {
            return SingleResponse.of(new ArrayList<>());
        }

        // 构建字段ID到模块字段信息的映射（用于获取排序号）
        Map<Long, ContractModuleFieldEntity> moduleFieldMap = moduleFields.stream()
                .collect(Collectors.toMap(ContractModuleFieldEntity::getFieldId, moduleField -> moduleField));

        // 分离父字段和子字段
        Map<Long, List<ContractFieldEntity>> parentChildMap = fields.stream()
                .filter(field -> field.getParentFieldId() != null)
                .collect(Collectors.groupingBy(ContractFieldEntity::getParentFieldId));

        // 获取所有父字段，按fieldOrder排序
        List<ContractFieldEntity> parentFields = fields.stream()
                .filter(field -> field.getParentFieldId() == null)
                .sorted((f1, f2) -> {
                    // 按照fieldOrder排序
                    ContractModuleFieldEntity mf1 = moduleFieldMap.get(f1.getId());
                    ContractModuleFieldEntity mf2 = moduleFieldMap.get(f2.getId());
                    Integer order1 = mf1 != null ? mf1.getFieldOrder() : Integer.MAX_VALUE;
                    Integer order2 = mf2 != null ? mf2.getFieldOrder() : Integer.MAX_VALUE;
                    return order1.compareTo(order2);
                })
                .collect(Collectors.toList());

        // 构建返回结果
        List<ContractFieldShowDTO> result = new ArrayList<>();
        for (ContractFieldEntity parentField : parentFields) {
            // 添加父字段
            ContractFieldShowDTO parentDto = new ContractFieldShowDTO();
            BeanUtils.copyProperties(parentField, parentDto);
            ContractModuleFieldEntity parentModuleField = moduleFieldMap.get(parentField.getId());
            if (parentModuleField != null) {
                parentDto.setFieldOrder(parentModuleField.getFieldOrder());
                parentDto.setModuleId(parentModuleField.getModuleId());
            }
            result.add(parentDto);

            // 添加子字段，按fieldOrder排序
            List<ContractFieldEntity> children = parentChildMap.getOrDefault(parentField.getId(), new ArrayList<>());
            if (!CollectionUtils.isEmpty(children)) {
                List<ContractFieldShowDTO> collect = children.stream()
                        .sorted((c1, c2) -> {
                            // 按照fieldOrder排序
                            ContractModuleFieldEntity cmf1 = moduleFieldMap.get(c1.getId());
                            ContractModuleFieldEntity cmf2 = moduleFieldMap.get(c2.getId());
                            Integer cOrder1 = cmf1 != null ? cmf1.getFieldOrder() : Integer.MAX_VALUE;
                            Integer cOrder2 = cmf2 != null ? cmf2.getFieldOrder() : Integer.MAX_VALUE;
                            return cOrder1.compareTo(cOrder2);
                        })
                        .map(childField -> {
                            ContractFieldShowDTO childDto = new ContractFieldShowDTO();
                            BeanUtils.copyProperties(childField, childDto);
                            ContractModuleFieldEntity childModuleField = moduleFieldMap.get(childField.getId());
                            if (childModuleField != null) {
                                childDto.setFieldOrder(childModuleField.getFieldOrder());
                                childDto.setModuleId(childModuleField.getModuleId());
                            }
                            return childDto;
                        }).collect(Collectors.toList());
                parentDto.setChildren(collect);
            }
        }

        // 重新添加缓存
//        redisService.setCacheList(RedisKeyConstant.Business.CONTRACT_MODULE_PREFIX + moduleId, result);

        return SingleResponse.of(result);
    }

    /**
     * 新增合同字段
     *
     * @param moduleId
     * @param contractFieldAddDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse createContractField(Integer moduleId, ContractFieldAddDTO contractFieldAddDTO) {
        // 参数校验
        if (moduleId == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同模块ID不能为空");
        }
        if (!moduleId.equals(contractFieldAddDTO.getModuleId())) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "模块ID不匹配");
        }
        if (contractFieldAddDTO == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同字段数据不能为空");
        }
        if (StringUtils.isEmpty(contractFieldAddDTO.getFieldName()) || StringUtils.isEmpty(contractFieldAddDTO.getCode())) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), ResponseCodeEnum.PARAMETER_ERROR.getMsg());
        }

        // 获取合同模块信息
        ContractModuleEntity contractModuleEntity = contractModuleService.getById(moduleId);
        if (contractModuleEntity == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同模块不存在");
        }
        if (!contractModuleEntity.getIsEnabled()) {
            return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "合同模块已禁用");
        }

        // 查询模块下字段
        List<Long> moduleFieldIds = contractModuleFieldService.list(new LambdaQueryWrapper<ContractModuleFieldEntity>().eq(ContractModuleFieldEntity::getModuleId, moduleId))
                .stream().map(ContractModuleFieldEntity::getFieldId).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(moduleFieldIds)) {
            // 检查字段名称是否重复
            LambdaQueryWrapper<ContractFieldEntity> nameWrapper = new LambdaQueryWrapper<>();
            nameWrapper.in(ContractFieldEntity::getId, moduleId);
            nameWrapper.eq(ContractFieldEntity::getFieldName, contractFieldAddDTO.getFieldName());
            long nameCount = contractFieldService.count(nameWrapper);
            if (nameCount > 0) {
                return SingleResponse.failure(ResponseCodeEnum.DATA_ALREADY_EXISTS.getCode(), "合同字段名称已存在");
            }
        }
        long codeCount = contractFieldService.count(Wrappers.<ContractFieldEntity>lambdaQuery()
                .eq(ContractFieldEntity::getCode, contractFieldAddDTO.getCode()));
        if (codeCount > 0) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_ALREADY_EXISTS.getCode(), "合同字段编码已存在");
        }
        if (!contractFieldAddDTO.getCode().matches("^[a-zA-Z_][a-zA-Z0-9_]*$")) {
            log.error("字段编码格式错误：{}", contractFieldAddDTO.getCode());
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), ResponseCodeEnum.PARAMETER_ERROR.getMsg());
        }

        // 如果有父字段，检查父字段是否存在且有效
        Long parentFieldId = contractFieldAddDTO.getParentFieldId();
        if (parentFieldId != null) {
            ContractFieldEntity parentField = contractFieldService.getById(parentFieldId);
            if (parentField == null) {
                return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "父字段不存在");
            }
            if (!parentField.getIsEnabled()) {
                return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "父字段已禁用");
            }
            if (parentField.getParentFieldId() != null) {
                return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "父字段不能是子字段");
            }
        }

        // 创建合同字段
        ContractFieldEntity contractFieldEntity = new ContractFieldEntity();
        BeanUtils.copyProperties(contractFieldAddDTO, contractFieldEntity);
        contractFieldEntity.setFieldOptions(JSON.toJSONString(contractFieldAddDTO.getFieldOptionsMap()));
        contractFieldEntity.setIsEnabled(true);
        contractFieldService.save(contractFieldEntity);

        // 添加缓存
        log.info("新增字段成功，字段编码: {}", contractFieldEntity.getCode());
        // 更新缓存(删除模块缓存，添加字段缓存)
        redisService.deleteObject(RedisKeyConstant.Business.CONTRACT_MODULE_PREFIX + moduleId);
        redisService.setHashObject(RedisKeyConstant.Business.CONTRACT_FIELD_PREFIX + contractFieldEntity.getId(), contractFieldEntity);

        // 获取当前模块下的最大排序号
        LambdaQueryWrapper<ContractModuleFieldEntity> orderWrapper = new LambdaQueryWrapper<>();
        orderWrapper.eq(ContractModuleFieldEntity::getModuleId, moduleId)
                .orderByDesc(ContractModuleFieldEntity::getFieldOrder)
                .last("LIMIT 1");
        // 如果有父字段，则根据父字段的排序号获取最大排序号
        List<Long> ids;// 获取模块下的一级字段id
        if (Objects.nonNull(contractFieldAddDTO.getParentFieldId())) {
            // 获取父类字段下的字段id
            ids = contractFieldService.list(new LambdaQueryWrapper<ContractFieldEntity>().eq(ContractFieldEntity::getParentFieldId, contractFieldAddDTO.getParentFieldId()).select(ContractFieldEntity::getId))
                    .stream().map(ContractFieldEntity::getId).collect(Collectors.toList());
        } else {
            ids = contractFieldService.list(new LambdaQueryWrapper<ContractFieldEntity>().eq(ContractFieldEntity::getParentFieldId, null).select(ContractFieldEntity::getId))
                    .stream().map(ContractFieldEntity::getId).collect(Collectors.toList());
        }
        if (!ids.isEmpty()) {
            orderWrapper.in(ContractModuleFieldEntity::getFieldId, ids);
        }
        ContractModuleFieldEntity maxOrderField = contractModuleFieldService.getOne(orderWrapper);
        Integer fieldOrder = maxOrderField != null ? maxOrderField.getFieldOrder() + 1 : 1;

        // 创建模块字段关联
        ContractModuleFieldEntity moduleField = new ContractModuleFieldEntity();
        moduleField.setModuleId(moduleId);
        moduleField.setFieldId(contractFieldEntity.getId());
        moduleField.setFieldOrder(fieldOrder);
        contractModuleFieldService.save(moduleField);

        return SingleResponse.success();
    }

    /**
     * 获取合同字段详情
     *
     * @param moduleId
     * @param id
     * @return
     */
    public SingleResponse<ContractFieldDetailShowDTO> getContractFieldById(Integer moduleId, Long id) {
        // 参数校验
        if (Objects.isNull(id) || Objects.isNull(moduleId)) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "参数错误");
        }

        // 获取合同模块信息
        ContractModuleEntity contractModuleEntity = contractModuleService.getById(moduleId);
        if (Objects.isNull(contractModuleEntity)) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同模块不存在");
        }
        if (!contractModuleEntity.getIsEnabled()) {
            return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "合同模块已禁用");
        }

        // 获取合同字段信息
        ContractFieldEntity contractFieldEntity = contractFieldService.getById(id);
        if (Objects.isNull(contractFieldEntity)) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同字段不存在");
        }
        if (!contractFieldEntity.getIsEnabled()) {
            return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "合同字段已禁用");
        }

        // 获取模块字段关联信息
        LambdaQueryWrapper<ContractModuleFieldEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ContractModuleFieldEntity::getModuleId, moduleId)
                .eq(ContractModuleFieldEntity::getFieldId, id);
        ContractModuleFieldEntity moduleField = contractModuleFieldService.getOne(wrapper);
        if (Objects.isNull(moduleField)) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同字段未关联到该模块");
        }

        // 构建返回对象
        ContractFieldDetailShowDTO detailDTO = new ContractFieldDetailShowDTO();
        BeanUtils.copyProperties(contractFieldEntity, detailDTO);
        detailDTO.setFieldOptionsMap(JSON.parseObject(contractFieldEntity.getFieldOptions(), Map.class));

        // 如果有父字段，获取父字段信息并检查状态
        if (contractFieldEntity.getParentFieldId() != null) {
            ContractFieldEntity parentField = contractFieldService.getById(contractFieldEntity.getParentFieldId());
            if (Objects.isNull(parentField)) {
                return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "父字段不存在");
            }
            if (!parentField.getIsEnabled()) {
                return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "父字段已禁用");
            }
            detailDTO.setParentFieldName(parentField.getFieldName());
        }
        // 查看子字段
        List<Long> childList = contractFieldService.list(new LambdaQueryWrapper<ContractFieldEntity>()
                        .eq(ContractFieldEntity::getParentFieldId, id)
                        .select(ContractFieldEntity::getId))
                .stream().map(ContractFieldEntity::getId).collect(Collectors.toList());
        if (!childList.isEmpty()) {
            List<ContractFieldDetailShowDTO> collect = childList.stream().map(child -> {
                SingleResponse<ContractFieldDetailShowDTO> contractFieldById = getContractFieldById(moduleId, child);
                return contractFieldById.getData();
            }).collect(Collectors.toList());
            detailDTO.setChildren(collect);
        }


        return SingleResponse.of(detailDTO);
    }

    /**
     * 修改合同字段
     *
     * @param moduleId
     * @param id
     * @param contractFieldUpdateDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse updateContractField(Integer moduleId, Long id, ContractFieldUpdateDTO contractFieldUpdateDTO) {
        // 参数校验
        if (moduleId == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同模块ID不能为空");
        }
        if (id == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同字段ID不能为空");
        }
        if (contractFieldUpdateDTO == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同字段数据不能为空");
        }
        if (StringUtils.isEmpty(contractFieldUpdateDTO.getFieldName())) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同字段名称不能为空");
        }
        if (!moduleId.equals(contractFieldUpdateDTO.getModuleId())) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同模块ID不匹配");
        }
        if (!id.equals(contractFieldUpdateDTO.getId())) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同字段ID不匹配");
        }

        // 获取合同模块信息
        ContractModuleEntity contractModuleEntity = contractModuleService.getById(moduleId);
        if (contractModuleEntity == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同模块不存在");
        }
        if (!contractModuleEntity.getIsEnabled()) {
            return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "合同模块已禁用");
        }

        // 获取原合同字段信息
        ContractFieldEntity existingField = contractFieldService.getById(id);
        if (existingField == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同字段不存在");
        }
        if (!existingField.getIsEnabled()) {
            return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "合同字段已禁用");
        }

        // 获取模块字段关联信息
        LambdaQueryWrapper<ContractModuleFieldEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ContractModuleFieldEntity::getModuleId, moduleId)
                .eq(ContractModuleFieldEntity::getFieldId, id);
        ContractModuleFieldEntity moduleField = contractModuleFieldService.getOne(wrapper);
        if (moduleField == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同字段未关联到该模块");
        }

        // 获取当前模块下的所有字段id
        List<Long> exitIds = contractModuleFieldService.list(new LambdaQueryWrapper<ContractModuleFieldEntity>()
                        .eq(ContractModuleFieldEntity::getModuleId, moduleId)
                        .select(ContractModuleFieldEntity::getFieldId))
                .stream().map(ContractModuleFieldEntity::getFieldId).collect(Collectors.toList());

        // 检查字段名称是否重复（排除自身）
        LambdaQueryWrapper<ContractFieldEntity> nameWrapper = new LambdaQueryWrapper<>();
        nameWrapper.eq(ContractFieldEntity::getFieldName, contractFieldUpdateDTO.getFieldName())
                .in(ContractFieldEntity::getId, exitIds)
                .ne(ContractFieldEntity::getId, id);
        long nameCount = contractFieldService.count(nameWrapper);
        if (nameCount > 0) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_ALREADY_EXISTS.getCode(), "合同字段名称已存在");
        }
        long codeCount = contractFieldService.count(Wrappers.<ContractFieldEntity>lambdaQuery()
                .eq(ContractFieldEntity::getCode, contractFieldUpdateDTO.getCode())
                .ne(ContractFieldEntity::getId, id));
        if (codeCount > 0) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_ALREADY_EXISTS.getCode(), ResponseCodeEnum.DATA_ALREADY_EXISTS.getMsg());
        }
        if (!contractFieldUpdateDTO.getCode().matches("^[a-zA-Z_][a-zA-Z0-9_]*$")) {
            log.error("字段编码格式错误：{}", contractFieldUpdateDTO.getCode());
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), ResponseCodeEnum.PARAMETER_ERROR.getMsg());
        }
        // 检查父字段变更
        Long oldParentId = existingField.getParentFieldId();
        Long newParentId = contractFieldUpdateDTO.getParentFieldId();
        boolean parentChanged = !Objects.equals(oldParentId, newParentId);

        if (parentChanged) {
            // 如果设置了新的父字段，检查父字段是否存在且有效
            if (newParentId != null) {
                ContractFieldEntity parentField = contractFieldService.getById(newParentId);
                if (parentField == null) {
                    return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "父字段不存在");
                }
                if (!parentField.getIsEnabled()) {
                    return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "父字段已禁用");
                }
                if (parentField.getParentFieldId() != null) {
                    return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "父字段不能是子字段");
                }
                // 检查是否形成循环引用
                if (newParentId.equals(id)) {
                    return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "不能将自己设为父字段");
                }
                if (isCircularReference(id, newParentId)) {
                    return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "不能形成循环引用");
                }
            }

            // 维护原父字段下的字段顺序
            if (oldParentId != null) {
                // 获取当前字段的排序号
                Integer currentOrder = moduleField.getFieldOrder();
                // 获取原父字段下排序号大于当前字段的字段
                List<ContractModuleFieldEntity> oldModuleFields = contractModuleFieldService.list(
                        new LambdaQueryWrapper<ContractModuleFieldEntity>()
                                .eq(ContractModuleFieldEntity::getModuleId, moduleId)
                                .gt(ContractModuleFieldEntity::getFieldOrder, currentOrder));
                // 将这些字段的排序号减1
                if (!CollectionUtils.isEmpty(oldModuleFields)) {
                    oldModuleFields.forEach(oldModuleField -> {
                        oldModuleField.setFieldOrder(oldModuleField.getFieldOrder() - 1);
                    });
                    contractModuleFieldService.updateBatchById(oldModuleFields);
                }
            }

            // 获取新父字段下的最大排序号
            LambdaQueryWrapper<ContractModuleFieldEntity> orderWrapper = new LambdaQueryWrapper<>();
            orderWrapper.eq(ContractModuleFieldEntity::getModuleId, moduleId);
            if (newParentId != null) {
                // 获取新父字段的模块字段关联
                LambdaQueryWrapper<ContractModuleFieldEntity> parentWrapper = new LambdaQueryWrapper<>();
                parentWrapper.eq(ContractModuleFieldEntity::getModuleId, moduleId)
                        .eq(ContractModuleFieldEntity::getFieldId, newParentId);
                ContractModuleFieldEntity parentModuleField = contractModuleFieldService.getOne(parentWrapper);
                if (parentModuleField == null) {
                    return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "父字段未关联到该模块");
                }
                // 获取父字段下的所有子字段
                List<ContractFieldEntity> childFields = contractFieldService.list(new LambdaQueryWrapper<ContractFieldEntity>()
                        .eq(ContractFieldEntity::getParentFieldId, newParentId));
                List<Long> childFieldIds = childFields.stream()
                        .map(ContractFieldEntity::getId)
                        .collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(childFieldIds)) {
                    orderWrapper.in(ContractModuleFieldEntity::getFieldId, childFieldIds);
                }
            } else {
                // 获取所有没有父字段的字段
                List<ContractFieldEntity> rootFields = contractFieldService.list(new LambdaQueryWrapper<ContractFieldEntity>()
                        .isNull(ContractFieldEntity::getParentFieldId));
                List<Long> rootFieldIds = rootFields.stream()
                        .map(ContractFieldEntity::getId)
                        .collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(rootFieldIds)) {
                    orderWrapper.in(ContractModuleFieldEntity::getFieldId, rootFieldIds);
                }
            }
            orderWrapper.orderByDesc(ContractModuleFieldEntity::getFieldOrder)
                    .last("LIMIT 1");
            ContractModuleFieldEntity maxOrderField = contractModuleFieldService.getOne(orderWrapper);
            Integer newOrder = maxOrderField != null ? maxOrderField.getFieldOrder() + 1 : 1;

            // 更新字段排序
            moduleField.setFieldOrder(newOrder);
            contractModuleFieldService.updateById(moduleField);
        }
        // 删除原缓存
        redisService.deleteObject(RedisKeyConstant.Business.CONTRACT_FIELD_PREFIX + id);
        redisService.deleteObject(RedisKeyConstant.Business.CONTRACT_MODULE_PREFIX + moduleId);

        // 更新合同字段
        ContractFieldEntity contractFieldEntity = new ContractFieldEntity();
        BeanUtils.copyProperties(contractFieldUpdateDTO, contractFieldEntity);
        contractFieldEntity.setFieldOptions(JSON.toJSONString(contractFieldUpdateDTO.getFieldOptionsMap()));
        // 保持原有的启用状态不变
        contractFieldEntity.setIsEnabled(existingField.getIsEnabled());
        boolean is = contractFieldService.updateById(contractFieldEntity);
        if (is) {
            redisService.setHashObject(RedisKeyConstant.Business.CONTRACT_FIELD_PREFIX + id, contractFieldEntity);
            log.info("更新合同字段缓存成功");
        } else {
            log.error("更新合同字段缓存失败,请联系管理员");
        }


        return SingleResponse.success();
    }

    /**
     * 检查是否形成循环引用
     *
     * @param fieldId
     * @param parentId
     * @return
     */
    private boolean isCircularReference(Long fieldId, Long parentId) {
        ContractFieldEntity parent = contractFieldService.getById(parentId);
        while (parent != null && parent.getParentFieldId() != null) {
            if (parent.getParentFieldId().equals(fieldId)) {
                return true;
            }
            parent = contractFieldService.getById(parent.getParentFieldId());
        }
        return false;
    }

    /**
     * 删除合同字段
     *
     * @param moduleId
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse deleteContractField(Integer moduleId, Long id) {
        // 参数校验
        if (moduleId == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同模块ID不能为空");
        }
        if (id == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同字段ID不能为空");
        }

        // 获取合同模块信息
        ContractModuleEntity contractModuleEntity = contractModuleService.getById(moduleId);
        if (contractModuleEntity == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同模块不存在");
        }

        // 获取合同字段信息
        ContractFieldEntity contractFieldEntity = contractFieldService.getById(id);
        if (contractFieldEntity == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同字段不存在");
        }
        if (contractFieldEntity.getIsSystem()) {
            ApiAssert.fail("系统字段不允许操作");
        }

        // 获取模块字段关联信息
        LambdaQueryWrapper<ContractModuleFieldEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ContractModuleFieldEntity::getModuleId, moduleId)
                .eq(ContractModuleFieldEntity::getFieldId, id);
        ContractModuleFieldEntity moduleField = contractModuleFieldService.getOne(wrapper);
        if (moduleField == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同字段未关联到该模块");
        }

        // 获取所有需要检查的字段ID（包括当前字段和子字段）
        List<Long> fieldIdsToCheck = new ArrayList<>();
        fieldIdsToCheck.add(id);
        boolean isFirstLevel = contractFieldEntity.getParentFieldId() == null;
        if (isFirstLevel) {
            // 如果是一级字段，获取所有子字段
            List<ContractFieldEntity> childFields = contractFieldService.list(
                    new LambdaQueryWrapper<ContractFieldEntity>()
                            .eq(ContractFieldEntity::getParentFieldId, id)
                            .select(ContractFieldEntity::getId));
            if (!CollectionUtils.isEmpty(childFields)) {
                fieldIdsToCheck.addAll(childFields.stream()
                        .map(ContractFieldEntity::getId)
                        .collect(Collectors.toList()));
            }
        }

        // 检查字段及其子字段是否在流程中使用
        LambdaQueryWrapper<ContractWorkflowFormFieldEntity> formFieldWrapper = new LambdaQueryWrapper<>();
        formFieldWrapper.in(ContractWorkflowFormFieldEntity::getFieldId, fieldIdsToCheck);
        long formFieldCount = contractWorkflowFormFieldService.count(formFieldWrapper);
        if (formFieldCount > 0) {
            return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "字段或其子字段在流程中使用，无法删除");
        }

        // 获取当前字段的排序号
        Integer currentOrder = moduleField.getFieldOrder();

        // 删除模块字段关联（包括子字段的关联）
        contractModuleFieldService.remove(new LambdaQueryWrapper<ContractModuleFieldEntity>()
                .eq(ContractModuleFieldEntity::getModuleId, moduleId)
                .in(ContractModuleFieldEntity::getFieldId, fieldIdsToCheck));

        // 删除合同字段（包括子字段）
        contractFieldService.removeByIds(fieldIdsToCheck);

        // 字段删除后从缓存中移除
        contractFieldService.listByIds(fieldIdsToCheck).forEach(item -> {
            redisService.deleteObject(RedisKeyConstant.Business.CONTRACT_FIELD_PREFIX + item.getId());
        });
        redisService.deleteObject(RedisKeyConstant.Business.CONTRACT_MODULE_PREFIX + moduleId);

        // 维护其他字段的排序号
        LambdaQueryWrapper<ContractModuleFieldEntity> orderWrapper = new LambdaQueryWrapper<>();
        orderWrapper.eq(ContractModuleFieldEntity::getModuleId, moduleId)
                .gt(ContractModuleFieldEntity::getFieldOrder, currentOrder);

        if (isFirstLevel) {
            // 一级字段：维护所有一级字段的顺序
            List<ContractFieldEntity> rootFields = contractFieldService.list(
                    new LambdaQueryWrapper<ContractFieldEntity>()
                            .isNull(ContractFieldEntity::getParentFieldId));
            if (!CollectionUtils.isEmpty(rootFields)) {
                List<Long> rootFieldIds = rootFields.stream()
                        .map(ContractFieldEntity::getId)
                        .collect(Collectors.toList());
                orderWrapper.in(ContractModuleFieldEntity::getFieldId, rootFieldIds);
            }
        } else {
            // 二级字段：维护同一父字段下的其他二级字段的顺序
            List<ContractFieldEntity> siblingFields = contractFieldService.list(
                    new LambdaQueryWrapper<ContractFieldEntity>()
                            .eq(ContractFieldEntity::getParentFieldId, contractFieldEntity.getParentFieldId()));
            if (!CollectionUtils.isEmpty(siblingFields)) {
                List<Long> siblingFieldIds = siblingFields.stream()
                        .map(ContractFieldEntity::getId)
                        .collect(Collectors.toList());
                orderWrapper.in(ContractModuleFieldEntity::getFieldId, siblingFieldIds);
            }
        }

        List<ContractModuleFieldEntity> moduleFields = contractModuleFieldService.list(orderWrapper);
        if (!CollectionUtils.isEmpty(moduleFields)) {
            moduleFields.forEach(field -> {
                field.setFieldOrder(field.getFieldOrder() - 1);
            });
            contractModuleFieldService.updateBatchById(moduleFields);
        }

        return SingleResponse.success();
    }

    /**
     * 合同字段排序
     *
     * @param moduleId
     * @param contractFieldSortDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse sortContractFields(Integer moduleId, ContractFieldSortDTO contractFieldSortDTO) {
        // 参数校验
        if (moduleId == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同模块ID不能为空");
        }
        if (contractFieldSortDTO == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "排序数据不能为空");
        }
        if (!moduleId.equals(contractFieldSortDTO.getModuleId())) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "模块ID不对应");
        }
        if (contractFieldSortDTO.getFieldId() == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "合同字段ID不能为空");
        }
        if (contractFieldSortDTO.getFieldOrder() == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "排序值不能为空");
        }

        // 获取合同模块信息
        ContractModuleEntity contractModuleEntity = contractModuleService.getById(moduleId);
        if (contractModuleEntity == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同模块不存在");
        }
        if (!contractModuleEntity.getIsEnabled()) {
            return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "合同模块已禁用");
        }

        // 获取合同字段信息
        ContractFieldEntity contractFieldEntity = contractFieldService.getById(contractFieldSortDTO.getFieldId());
        if (contractFieldEntity == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同字段不存在");
        }

        // 获取模块字段关联信息
        LambdaQueryWrapper<ContractModuleFieldEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ContractModuleFieldEntity::getModuleId, moduleId)
                .eq(ContractModuleFieldEntity::getFieldId, contractFieldSortDTO.getFieldId());
        ContractModuleFieldEntity moduleField = contractModuleFieldService.getOne(wrapper);
        if (moduleField == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "合同字段未关联到该模块");
        }

        // 获取当前排序值
        Integer currentSort = moduleField.getFieldOrder();
        Integer newSort = contractFieldSortDTO.getFieldOrder();

        // 判断是一级字段还是二级字段
        boolean isFirstLevel = contractFieldEntity.getParentFieldId() == null;

        // 构建查询条件
        LambdaQueryWrapper<ContractModuleFieldEntity> orderWrapper = new LambdaQueryWrapper<>();
        orderWrapper.eq(ContractModuleFieldEntity::getModuleId, moduleId);

        if (isFirstLevel) {
            // 一级字段：获取所有一级字段
            List<ContractFieldEntity> rootFields = contractFieldService.list(
                    new LambdaQueryWrapper<ContractFieldEntity>()
                            .isNull(ContractFieldEntity::getParentFieldId)
                            .select(ContractFieldEntity::getId));
            if (!CollectionUtils.isEmpty(rootFields)) {
                List<Long> rootFieldIds = rootFields.stream()
                        .map(ContractFieldEntity::getId)
                        .collect(Collectors.toList());
                orderWrapper.in(ContractModuleFieldEntity::getFieldId, rootFieldIds);
            }
        } else {
            // 二级字段：获取同一父字段下的所有二级字段
            List<ContractFieldEntity> siblingFields = contractFieldService.list(
                    new LambdaQueryWrapper<ContractFieldEntity>()
                            .eq(ContractFieldEntity::getParentFieldId, contractFieldEntity.getParentFieldId())
                            .select(ContractFieldEntity::getId));
            if (!CollectionUtils.isEmpty(siblingFields)) {
                List<Long> siblingFieldIds = siblingFields.stream()
                        .map(ContractFieldEntity::getId)
                        .collect(Collectors.toList());
                orderWrapper.in(ContractModuleFieldEntity::getFieldId, siblingFieldIds);
            }
        }

        if (currentSort < newSort) {
            // 向后移动：将中间的类型排序值减1
            orderWrapper.gt(ContractModuleFieldEntity::getFieldOrder, currentSort)
                    .le(ContractModuleFieldEntity::getFieldOrder, newSort);
            List<ContractModuleFieldEntity> updateList = contractModuleFieldService.list(orderWrapper);
            for (ContractModuleFieldEntity field : updateList) {
                field.setFieldOrder(field.getFieldOrder() - 1);
            }
            contractModuleFieldService.updateBatchById(updateList);
        } else if (currentSort > newSort) {
            // 向前移动：将中间的类型排序值加1
            orderWrapper.ge(ContractModuleFieldEntity::getFieldOrder, newSort)
                    .lt(ContractModuleFieldEntity::getFieldOrder, currentSort);
            List<ContractModuleFieldEntity> updateList = contractModuleFieldService.list(orderWrapper);
            for (ContractModuleFieldEntity field : updateList) {
                field.setFieldOrder(field.getFieldOrder() + 1);
            }
            contractModuleFieldService.updateBatchById(updateList);
        }

        // 更新当前字段的排序值
        moduleField.setFieldOrder(newSort);
        contractModuleFieldService.updateById(moduleField);

        return SingleResponse.success();
    }

    /**
     * 获取合同工作流列表
     *
     * @param pageNo
     * @param pageSize
     * @param contractWorkflowListQueryDTO
     * @return
     */
    public SingleResponse<IPage<ContractWorkflowListPageDTO>> listContractWorkflows(Integer pageNo, Integer pageSize, ContractWorkflowListQueryDTO contractWorkflowListQueryDTO) {
        // 参数校验
        if (contractWorkflowListQueryDTO == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "查询参数不能为空");
        }
        if (contractWorkflowListQueryDTO.getPageNo() == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "页码不能为空");
        }
        if (contractWorkflowListQueryDTO.getPageSize() == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "每页条数不能为空");
        }
        if (!pageNo.equals(contractWorkflowListQueryDTO.getPageNo()) || !pageSize.equals(contractWorkflowListQueryDTO.getPageSize())) {
            return SingleResponse.failure(ResponseCodeEnum.PARAM_BINDING_EXCEPTION.getCode(), "分页参数错误对应错误");
        }
        List<String> userTenantKeys = AuthUtil.getUserTenantKeys();
        // 添加判空处理
        if (userTenantKeys == null) {
            userTenantKeys = new ArrayList<>();
        }
        LambdaQueryWrapper<ContractWorkflowEntity> wrapper = new LambdaQueryWrapper<>();
//        if (AuthUtil.isSuperAdmin()){
//            // 超级管理员不做限制
//        } else if (userTenantKeys != null && !userTenantKeys.isEmpty()) {
//            wrapper.in(ContractWorkflowEntity::getSysTenantKey, userTenantKeys);
//        } else if (userTenantKeys != null) {
//            // 空列表表示没有任何租户权限
//            wrapper.eq(ContractWorkflowEntity::getSysTenantKey, "NO_PERMISSION");
//        }

        // 分页查询
        Page<ContractWorkflowEntity> page = new Page<>(contractWorkflowListQueryDTO.getPageNo(), contractWorkflowListQueryDTO.getPageSize());
        IPage<ContractWorkflowEntity> workflowPage = contractWorkflowService.page(page, wrapper
                .eq(ContractWorkflowEntity::getWorkflowType, contractWorkflowListQueryDTO.getWorkflowType())
                .orderByDesc(ContractWorkflowEntity::getPriority));

        if (workflowPage.getRecords().isEmpty()) {
            return SingleResponse.of(new Page<>());
        }

        // 获取所有工作流ID
        List<Long> workflowIds = workflowPage.getRecords().stream()
                .filter(Objects::nonNull)
                .map(ContractWorkflowEntity::getId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        // 获取租户关联
//        List<String> sysTenantKey = workflowPage.getRecords().stream()
//                .map(ContractWorkflowEntity::getSysTenantKey)
//                .distinct()
//                .toList();
//
//        // 获取租户名称
//        Map<String, String> tenantNameMap = sysDepartmentService.list(Wrappers.<SysDepartment>lambdaQuery()
//                        .in(SysDepartment::getSysTenantKey, sysTenantKey)
//                        .and(childWrapper -> childWrapper
//                                .eq(SysDepartment::getPid, 0L)
//                                .or()
//                                .eq(SysDepartment::getIndependentFlag, 1))
//                        .select(SysDepartment::getName, SysDepartment::getSysTenantKey))
//                .stream()
//                .collect(Collectors.toMap(SysDepartment::getSysTenantKey, SysDepartment::getName));

        if (CollectionUtils.isEmpty(workflowIds)) {
            return SingleResponse.of(new Page<>(pageNo, pageSize));
        }

        // 获取工作流关联的合同类型
        LambdaQueryWrapper<ContractWorkflowTypeEntity> typeWrapper = new LambdaQueryWrapper<>();
        typeWrapper.in(ContractWorkflowTypeEntity::getWorkflowId, workflowIds);
        List<ContractWorkflowTypeEntity> workflowTypes = contractWorkflowTypeService.list(typeWrapper);

        // 获取所有合同类型ID
        List<Integer> typeIds = workflowTypes.stream()
                .filter(Objects::nonNull)
                .map(ContractWorkflowTypeEntity::getContractTypeId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        Map<Integer, String> typeMap = new HashMap<>();
        Map<Long, List<Integer>> workflowTypeMap = new HashMap<>();

        if (!CollectionUtils.isEmpty(typeIds)) {
            // 获取合同类型信息
            List<ContractTypeEntity> contractTypes = contractTypeService.list(new LambdaQueryWrapper<ContractTypeEntity>()
                    .eq(ContractTypeEntity::getIsEnabled, true)
                    .in(ContractTypeEntity::getId, typeIds)
                    .select(ContractTypeEntity::getId, ContractTypeEntity::getTypeName));
            typeMap = contractTypes.stream()
                    .filter(Objects::nonNull)
                    .filter(type -> type.getId() != null && type.getTypeName() != null)
                    .collect(Collectors.toMap(ContractTypeEntity::getId, ContractTypeEntity::getTypeName));

            // 构建工作流ID到合同类型ID的映射
            workflowTypeMap = workflowTypes.stream()
                    .filter(Objects::nonNull)
                    .filter(wt -> wt.getWorkflowId() != null && wt.getContractTypeId() != null)
                    .collect(Collectors.groupingBy(
                            ContractWorkflowTypeEntity::getWorkflowId,
                            Collectors.mapping(ContractWorkflowTypeEntity::getContractTypeId, Collectors.toList())
                    ));
        }


        // 获取流程定义id - 查询每个processKey对应的最新版本流程
        List<String> processKeys = workflowPage.getRecords().stream()
                .filter(Objects::nonNull)
                .map(ContractWorkflowEntity::getProcessKey)
                .filter(Objects::nonNull)
                .filter(key -> !key.trim().isEmpty())
                .collect(Collectors.toList());
        Map<String, FlwProcess> processMap;
        if (!CollectionUtils.isEmpty(processKeys)) {
            // 查询所有匹配processKey的流程
            List<FlwProcess> allProcesses = flwProcessMapper.selectList(new LambdaQueryWrapper<FlwProcess>()
                    .in(FlwProcess::getProcessKey, processKeys)
                    .select(FlwProcess::getId, FlwProcess::getProcessKey, FlwProcess::getProcessName, FlwProcess::getProcessVersion));

            // 按processKey分组，并在每组中找到版本最大的流程
            processMap = allProcesses.stream()
                    .filter(Objects::nonNull)
                    .filter(process -> process.getProcessKey() != null)
                    .collect(Collectors.groupingBy(FlwProcess::getProcessKey))
                    .values()
                    .stream()
                    .map(processes -> processes.stream()
                            .filter(Objects::nonNull)
                            .max(Comparator.comparing(FlwProcess::getProcessVersion))
                            .orElse(null))
                    .filter(Objects::nonNull)
                    .filter(process -> process.getProcessKey() != null)
                    .collect(Collectors.toMap(FlwProcess::getProcessKey, flw -> flw));
        } else {
            processMap = new HashMap<>();
        }

//        // 获取关联部门id
//        List<ContractWorkflowDepartment> departments = contractWorkflowDepartmentService.list(new LambdaQueryWrapper<ContractWorkflowDepartment>()
//                .in(ContractWorkflowDepartment::getWorkflowId, workflowIds));
//        List<Long> departmentIds = departments.stream().map(ContractWorkflowDepartment::getDepartmentId).distinct().collect(Collectors.toList());
//        Map<Long, List<ContractWorkflowDepartment>> workflowDepartmentMap = departments.stream().collect(Collectors.groupingBy(ContractWorkflowDepartment::getWorkflowId));
//        Map<Long, String> departmentMap;
//        if (!CollectionUtils.isEmpty(departmentIds)) {
//            departmentMap = sysDepartmentService.list(new LambdaQueryWrapper<SysDepartment>()
//                            .in(SysDepartment::getId, departmentIds.stream().distinct().collect(Collectors.toList()))
//                            .select(SysDepartment::getId, SysDepartment::getName))
//                    .stream().collect(Collectors.toMap(SysDepartment::getId, SysDepartment::getName));
//        } else {
//            departmentMap = new HashMap<>();
//        }
//
//        // 获取法人关联信息
//        List<ContractWorkflowLegal> workflowLegals = contractWorkflowLegalService.list(Wrappers.<ContractWorkflowLegal>lambdaQuery()
//                .in(ContractWorkflowLegal::getWorkflowId, workflowIds)
//                .select(ContractWorkflowLegal::getWorkflowId, ContractWorkflowLegal::getLegalId));
//        Map<Integer, LegalEntityDetailEntity> legalMap;
//        Map<Long, List<ContractWorkflowLegal>> workflowLegalMap;
//        if (CollectionUtils.isEmpty(workflowLegals)) {
//            legalMap = new HashMap<>();
//            workflowLegalMap = new HashMap<>();
//        } else {
//            legalMap = legalEntityDetailMapper.selectByIds(workflowLegals.stream().map(ContractWorkflowLegal::getLegalId).distinct().toList())
//                    .stream().collect(Collectors.toMap(LegalEntityDetailEntity::getId, detail -> detail));
//
//            workflowLegalMap = workflowLegals.stream().collect(Collectors.groupingBy(ContractWorkflowLegal::getWorkflowId));
//        }

        // 构建返回结果
        Map<Long, List<Integer>> finalWorkflowTypeMap = workflowTypeMap;
        Map<Integer, String> finalTypeMap = typeMap;
        IPage<ContractWorkflowListPageDTO> resultPage = workflowPage.convert(workflow -> {
            ContractWorkflowListPageDTO dto = new ContractWorkflowListPageDTO();

            // 添加判空处理
            if (workflow == null) {
                return dto;
            }

            // 设置基本信息
            BeanUtils.copyProperties(workflow, dto);
//            dto.setTenantName(tenantNameMap.get(workflow.getSysTenantKey()));

            // 获取该工作流关联的所有合同类型名称
            Long workflowId = workflow.getId();
            if (workflowId != null) {
                List<Integer> workflowTypeIds = finalWorkflowTypeMap.getOrDefault(workflowId, new ArrayList<>());
                if (!CollectionUtils.isEmpty(workflowTypeIds)) {
                    List<String> typeNames = workflowTypeIds.stream()
                            .filter(Objects::nonNull)
                            .map(finalTypeMap::get)
                            .filter(Objects::nonNull)
                            .collect(Collectors.toList());
                    dto.setScope(typeNames);
                }
            }

            String processKey = workflow.getProcessKey();
            if (processKey != null && !processKey.trim().isEmpty() && processMap.containsKey(processKey)) {
                FlwProcess process = processMap.get(processKey);
                if (process != null) {
                    dto.setProcessName(process.getProcessName());
                    dto.setProcessId(process.getId());
                }
            }
//            if (workflowDepartmentMap.containsKey(workflow.getId())) {
//                List<ContractWorkflowDepartment> workflowDepartments = workflowDepartmentMap.get(workflow.getId());
//                List<String> departmentNames = workflowDepartments.stream()
//                        .map(ContractWorkflowDepartment::getDepartmentId)
//                        .map(departmentMap::get)
//                        .filter(Objects::nonNull)
//                        .collect(Collectors.toList());
//                dto.setDepartment(departmentNames);
//            }
//            // 获取该工作流关联的法人信息
//            if (!CollectionUtils.isEmpty(workflowLegals) && workflowLegalMap.containsKey(workflow.getId())) {
//                List<String> legalName = workflowLegalMap.get(workflow.getId()).stream()
//                        .map(ContractWorkflowLegal::getLegalId)
//                        .map(legalMap::get)
//                        .map(LegalEntityDetailEntity::getLegalEntityName)
//                        .collect(Collectors.toList());
//                dto.setLegalName(legalName);
//            }


            return dto;
        });

        return SingleResponse.of(resultPage);
    }

    /**
     * 新增合同工作流
     *
     * @param workflowAddDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse<WorkflowShowDTO> createContractWorkflow(ContractWorkflowAddDTO workflowAddDTO) {
        // 参数校验
        if (workflowAddDTO == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "工作流数据不能为空");
        }
        if (StringUtils.isEmpty(workflowAddDTO.getWorkflowName())) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "工作流名称不能为空");
        }

        FlwProcess flwProcess = flwProcessMapper.selectById(workflowAddDTO.getProcessId());
        if (null == flwProcess) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "流程定义不存在");
        }

        // 检查工作流名称是否重复
        LambdaQueryWrapper<ContractWorkflowEntity> nameWrapper = new LambdaQueryWrapper<>();
        nameWrapper.eq(ContractWorkflowEntity::getWorkflowName, workflowAddDTO.getWorkflowName())
                .eq(ContractWorkflowEntity::getWorkflowType, workflowAddDTO.getWorkflowType());
        long count = contractWorkflowService.count(nameWrapper);
        if (count > 0) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_ALREADY_EXISTS.getCode(), "工作流名称已存在");
        }

//        List<Long> departmentIds = workflowAddDTO.getDepartment();
//        if (!CollectionUtils.isEmpty(departmentIds)){
//            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), ResponseCodeEnum.PARAMETER_ERROR.getMsg());
//        }
//        Map<String, List<SysDepartment>> departmentMap = sysDepartmentService.list(Wrappers.<SysDepartment>lambdaQuery()
//                        .in(SysDepartment::getId, departmentIds)
//                        .select(SysDepartment::getId, SysDepartment::getSysTenantKey))
//                .stream()
//                .collect(Collectors.groupingBy(SysDepartment::getSysTenantKey));
//
//        departmentMap.forEach((sysTenantKey, departmentList) -> {
//            if (CollectionUtils.isEmpty(departmentList)){
//                return;
//            }
        // 第一步：先保存工作流主表，确保获得主键ID
        ContractWorkflowEntity workflow = new ContractWorkflowEntity();
        workflow.setWorkflowName(workflowAddDTO.getWorkflowName());
        workflow.setIsEnabled(true);
        workflow.setIsPublished(false);
//            workflow.setSysTenantKey(sysTenantKey);
        workflow.setWorkflowType(workflowAddDTO.getWorkflowType());
        workflow.setProcessKey(flwProcess.getProcessKey());
        workflow.setPriority(workflowAddDTO.getPriority());
        contractWorkflowService.save(workflow);
        Long workflowId = workflow.getId();

        log.info("工作流主表保存成功，workflowId: {}", workflowId);

        // 第二步：在当前事务中并行执行其他关联数据保存
        saveWorkflowTypes(workflowId, workflowAddDTO.getScope());

        // 保存与法人公司关联
//            saveWorkflowLegal(workflowId, workflowAddDTO.getLegalIds());

        //
//            List<ContractWorkflowDepartment> departments = departmentList.stream().map(item -> {
//                ContractWorkflowDepartment department = new ContractWorkflowDepartment();
//                department.setWorkflowId(workflowId);
//                department.setDepartmentId(item.getId());
//                return department;
//            }).collect(Collectors.toList());
//
//            contractWorkflowDepartmentService.saveBatch(departments);
//        });

        // 更新缓存
        updateWorkflowCache(workflowAddDTO.getScope(),flwProcess.getProcessKey(),workflowAddDTO.getPriority());

        return SingleResponse.success();

    }

    private void updateWorkflowCache(List<Integer> scope, String processKey, Integer priority) {
        scope.forEach(item -> {
            Integer currentPriority = redisService.getCacheMapValue(RedisKeyConstant.Business.APPROVAL_TYPE_PROCESS_PREFIX + item, RedisCacheEnum.ProcessKeyTypeCache.PRIORITY.getValue());
            if (currentPriority == null || currentPriority < priority) {
                ProcessKeyTypeCache processKeyTypeCache = new ProcessKeyTypeCache();
                processKeyTypeCache.setProcessKey(processKey);
                processKeyTypeCache.setPriority(priority);
                redisService.setHashObject(RedisKeyConstant.Business.APPROVAL_TYPE_PROCESS_PREFIX + item, processKeyTypeCache);
            }
        });
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveWorkflowLegal(Long workflowId, List<Integer> legalIds) {
        if (!CollectionUtils.isEmpty(legalIds)) {
            contractWorkflowLegalService.saveBatch(legalIds.stream().map(item -> {
                ContractWorkflowLegal workflowLegal = new ContractWorkflowLegal();
                workflowLegal.setWorkflowId(workflowId);
                workflowLegal.setLegalId(item);
                return workflowLegal;
            }).toList());
            log.info("保存与法人公司关联成功，workflowId: {}", workflowId);
        }
    }


    /**
     * 初始化系统字段
     *
     * @param workflow
     */
    public void saveSystemField(ContractWorkflowEntity workflow) {
        // 保存系统模块字段
        List<Integer> SystemModuleIds = contractModuleService.list(new LambdaQueryWrapper<ContractModuleEntity>()
                        .eq(ContractModuleEntity::getIsEnabled, Boolean.TRUE)
                        .eq(ContractModuleEntity::getIsSystem, Boolean.TRUE)
                        .select(ContractModuleEntity::getId))
                .stream().map(ContractModuleEntity::getId).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(SystemModuleIds)) {
            log.info("没有系统模块");
            return;
        }
        List<ContractWorkflowModuleEntity> moduleEntities = SystemModuleIds.stream().map(item -> {
            ContractWorkflowModuleEntity workflowModule = new ContractWorkflowModuleEntity();
            workflowModule.setWorkflowId(workflow.getId());
            workflowModule.setModuleId(item);
            return workflowModule;
        }).collect(Collectors.toList());
        contractWorkflowModuleService.saveBatch(moduleEntities);

        // 获取系统模块下的所有字段
        List<ContractModuleFieldEntity> systemModuleFields = contractModuleFieldService.list(new LambdaQueryWrapper<ContractModuleFieldEntity>()
                .in(ContractModuleFieldEntity::getModuleId, SystemModuleIds)
                .select(ContractModuleFieldEntity::getFieldId, ContractModuleFieldEntity::getModuleId));

        if (CollectionUtils.isEmpty(systemModuleFields)) {
            log.info("系统模块没有字段");
            return;
        }

        // 获取字段详细信息
        List<Long> systemFieldIds = systemModuleFields.stream()
                .map(ContractModuleFieldEntity::getFieldId)
                .collect(Collectors.toList());
        List<ContractFieldEntity> systemFields = contractFieldService.listByIds(systemFieldIds).stream()
                .filter(field -> field.getIsEnabled())
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(systemFields)) {
            log.info("系统模块没有启用的字段");
            return;
        }

        // 获取所有字段类型
        Map<Long, String> fieldTypes = systemFields.stream().collect(Collectors.toMap(ContractFieldEntity::getId, ContractFieldEntity::getFieldType));

        // 按模块ID分组处理系统字段
        Map<Integer, List<ContractModuleFieldEntity>> systemModuleFieldMap = systemModuleFields.stream()
                .collect(Collectors.groupingBy(ContractModuleFieldEntity::getModuleId));

        List<ContractWorkflowFormFieldEntity> systemFormFields = new ArrayList<>();

        // 处理每个系统模块的字段
        for (Map.Entry<Integer, List<ContractModuleFieldEntity>> entry : systemModuleFieldMap.entrySet()) {
            Integer moduleId = entry.getKey();
            List<ContractModuleFieldEntity> moduleFieldList = entry.getValue();

            // 按父字段ID分组
            Map<Long, List<ContractModuleFieldEntity>> parentFieldMap = moduleFieldList.stream()
                    .collect(Collectors.groupingBy(field -> {
                        ContractFieldEntity contractFieldEntity = systemFields.stream()
                                .filter(f -> f.getId().equals(field.getFieldId()))
                                .findFirst()
                                .orElse(null);
                        // 使用0代替null作为一级字段的key
                        return contractFieldEntity != null && contractFieldEntity.getParentFieldId() != null ?
                                contractFieldEntity.getParentFieldId() : 0;
                    }));

            // 处理一级字段（key为0的组）
            List<ContractModuleFieldEntity> rootFields = parentFieldMap.getOrDefault(0, new ArrayList<>());
            int rootOrder = 1;
            for (ContractModuleFieldEntity rootField : rootFields) {
                ContractFieldEntity field = systemFields.stream()
                        .filter(f -> f.getId().equals(rootField.getFieldId()))
                        .findFirst()
                        .orElse(null);
                if (field != null) {
                    ContractWorkflowFormFieldEntity formField = new ContractWorkflowFormFieldEntity();
                    formField.setWorkflowId(workflow.getId());
                    formField.setModuleId(moduleId);
                    formField.setFieldId(field.getId());
                    formField.setIsRequired(field.getIsRequired());
                    formField.setFieldOrder(rootOrder++);
                    formField.setIsHidden(false);
                    // 系统字段开启，非系统字段不开启
                    formField.setIsEnabled(field.getIsSystem() != null && field.getIsSystem());
                    formField.setHelpContent(FieldTypeEnum.valueOf(fieldTypes.get(field.getId())).getValueScope());
                    systemFormFields.add(formField);

                    // 处理该一级字段下的二级字段
                    List<ContractModuleFieldEntity> childFields = parentFieldMap.getOrDefault(field.getId(), new ArrayList<>());
                    int childOrder = 1;
                    for (ContractModuleFieldEntity childField : childFields) {
                        ContractFieldEntity childContractField = systemFields.stream()
                                .filter(f -> f.getId().equals(childField.getFieldId()))
                                .findFirst()
                                .orElse(null);
                        if (childContractField != null) {
                            ContractWorkflowFormFieldEntity childFormField = new ContractWorkflowFormFieldEntity();
                            childFormField.setWorkflowId(workflow.getId());
                            childFormField.setModuleId(moduleId);
                            childFormField.setFieldId(childContractField.getId());
                            childFormField.setIsRequired(childContractField.getIsRequired());
                            childFormField.setFieldOrder(childOrder++);
                            childFormField.setIsHidden(false);
                            // 系统字段开启，非系统字段不开启
                            childFormField.setIsEnabled(childContractField.getIsSystem() != null && childContractField.getIsSystem());
                            childFormField.setHelpContent(FieldTypeEnum.valueOf(fieldTypes.get(childContractField.getId())).getValueScope());
                            systemFormFields.add(childFormField);
                        }
                    }
                }
            }
        }

        // 批量保存系统字段配置
        if (!systemFormFields.isEmpty()) {
            contractWorkflowFormFieldService.saveBatch(systemFormFields);
        }
    }

    /**
     * 保存工作流类型关联
     *
     * @param workflowId      工作流ID
     * @param contractTypeIds 合同类型ID列表
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveWorkflowTypes(Long workflowId, List<Integer> contractTypeIds) {
        if (!CollectionUtils.isEmpty(contractTypeIds)) {
            List<ContractWorkflowTypeEntity> workflowTypes = contractTypeIds.stream()
                    .map(typeId -> {
                        ContractWorkflowTypeEntity workflowType = new ContractWorkflowTypeEntity();
                        workflowType.setWorkflowId(workflowId);
                        workflowType.setContractTypeId(typeId);
                        return workflowType;
                    })
                    .collect(Collectors.toList());
            contractWorkflowTypeService.saveBatch(workflowTypes);
            log.info("工作流类型关联保存成功，workflowId: {}, typeCount: {}", workflowId, workflowTypes.size());
        }
    }


    /**
     * 创建标准工作流节点
     */
    private List<WorkflowNodeEntity> createStandardNodes(Integer workflowId) {
        List<NodeTypeEnum> nodeTypes = Arrays.asList(
                NodeTypeEnum.START, NodeTypeEnum.SUBMIT, NodeTypeEnum.APPROVE,
                NodeTypeEnum.SEAL, NodeTypeEnum.ARCHIVE, NodeTypeEnum.END
        );

        List<WorkflowNodeEntity> workflowNodes = new ArrayList<>();
        for (int i = 0; i < nodeTypes.size(); i++) {
            WorkflowNodeEntity workflowNode = new WorkflowNodeEntity();
            workflowNode.setWorkflowId(workflowId);
            workflowNode.setNodeName(nodeTypes.get(i).getMsg());
            workflowNode.setNodeType(nodeTypes.get(i));
            workflowNode.setOrderNum(i + 1);
            workflowNodes.add(workflowNode);
        }
        return workflowNodes;
    }

    /**
     * 创建顺序连接的边
     */
    private List<WorkflowEdgeEntity> createSequentialEdges(Integer workflowId, List<WorkflowNodeEntity> workflowNodes) {
        workflowNodes.sort(Comparator.comparingInt(WorkflowNodeEntity::getOrderNum));

        List<WorkflowEdgeEntity> workflowEdges = new ArrayList<>();
        for (int i = 0; i < workflowNodes.size() - 1; i++) {
            WorkflowEdgeEntity workflowEdge = new WorkflowEdgeEntity();
            workflowEdge.setWorkflowId(workflowId);
            workflowEdge.setSourceNodeId(workflowNodes.get(i).getId());
            workflowEdge.setTargetNodeId(workflowNodes.get(i + 1).getId());
            workflowEdges.add(workflowEdge);
        }
        return workflowEdges;
    }


    public SingleResponse saveWorkflow(Long workflowId, WorkflowSaveDTO workflowSaveDTO) {
        // 参数校验
        if (workflowId == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "工作流ID不能为空");
        }
        if (workflowSaveDTO == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "工作流保存数据不能为空");
        }

        // 查询工作流信息，与getDetail方法类似的校验逻辑
        ContractWorkflowEntity contractWorkflowEntity = contractWorkflowService.getById(workflowId);
        if (contractWorkflowEntity == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "工作流不存在");
        }
        if (!contractWorkflowEntity.getIsEnabled()) {
            return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "工作流已禁用");
        }

        // 租户隔离校验：通过工作流类型验证租户权限，与getDetail方法保持一致
        WorkflowTypeEntity workflowType = workflowTypeService.getById(contractWorkflowEntity.getTypeId());
        if (workflowType == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "工作流类型不存在");
        }

        try {
            // 保存工作流基本信息（名称）
            if (workflowSaveDTO.getWorkflowName() != null) {
                contractWorkflowEntity.setWorkflowName(workflowSaveDTO.getWorkflowName());
            }

            // 保存工作流范围（合同类型关联）
            if (workflowSaveDTO.getScope() != null) {
                String[] contractTypeIds = workflowSaveDTO.getScope().split(",");
                List<Integer> typeIdList = Arrays.stream(contractTypeIds)
                        .filter(s -> !s.isEmpty())
                        .map(Integer::valueOf)
                        .collect(Collectors.toList());

                // 删除原有关联
                contractWorkflowTypeService.remove(new LambdaQueryWrapper<ContractWorkflowTypeEntity>()
                        .eq(ContractWorkflowTypeEntity::getWorkflowId, workflowId));

                // 保存新关联
                if (!CollectionUtils.isEmpty(typeIdList)) {
                    List<ContractWorkflowTypeEntity> workflowTypes = typeIdList.stream()
                            .map(typeId -> {
                                ContractWorkflowTypeEntity entity = new ContractWorkflowTypeEntity();
                                entity.setWorkflowId(workflowId);
                                entity.setContractTypeId(typeId);
                                return entity;
                            })
                            .collect(Collectors.toList());
                    contractWorkflowTypeService.saveBatch(workflowTypes);
                }
            }

            // 1. 第一步：保存表单字段信息
            if (!CollectionUtils.isEmpty(workflowSaveDTO.getFormFields())) {
                // 收集所有需要保存的字段ID
                Set<Long> incomingFieldIds = new HashSet<>();
                List<ContractWorkflowFormFieldEntity> saveOrUpdateFields = new ArrayList<>();

                for (WorkflowFormFieldsListDTO moduleDTO : workflowSaveDTO.getFormFields()) {
                    if (!CollectionUtils.isEmpty(moduleDTO.getWorkflowFormFields())) {
                        for (WorkflowFormFieldDTO fieldDTO : moduleDTO.getWorkflowFormFields()) {
                            // 添加主字段
                            if (fieldDTO.getId() != null) {
                                incomingFieldIds.add(fieldDTO.getId());
                            }

                            ContractWorkflowFormFieldEntity workflowFormField = new ContractWorkflowFormFieldEntity();
                            workflowFormField.setId(fieldDTO.getId());
                            workflowFormField.setWorkflowId(workflowId);
                            workflowFormField.setModuleId(moduleDTO.getId());
                            workflowFormField.setFieldId(fieldDTO.getFieldId());
//                            workflowFormField.setIsRequired(fieldDTO.getIsRequired());
                            workflowFormField.setFieldOrder(fieldDTO.getFieldOrder());
                            workflowFormField.setPlaceholderText(fieldDTO.getPlaceholderText());
                            workflowFormField.setEmptyStateText(fieldDTO.getEmptyStateText());
                            workflowFormField.setIsHidden(fieldDTO.getIsHidden());
                            workflowFormField.setIsEnabled(fieldDTO.getIsEnabled() != null ? fieldDTO.getIsEnabled() : true);

                            // 处理helpContent，将Map转换为JSON字符串
                            if (fieldDTO.getHelpContent() != null) {
                                workflowFormField.setHelpContent(JSON.toJSONString(fieldDTO.getHelpContent()));
                            }
                            workflowFormField.setHelpDisplayType(fieldDTO.getHelpDisplayType());

                            saveOrUpdateFields.add(workflowFormField);

                            // 处理子字段
                            if (!CollectionUtils.isEmpty(fieldDTO.getChildFields())) {
                                for (WorkflowFormFieldDTO childField : fieldDTO.getChildFields()) {
                                    // 添加子字段ID
                                    if (childField.getId() != null) {
                                        incomingFieldIds.add(childField.getId());
                                    }

                                    ContractWorkflowFormFieldEntity childWorkflowFormField = new ContractWorkflowFormFieldEntity();
                                    childWorkflowFormField.setId(childField.getId());
                                    childWorkflowFormField.setWorkflowId(workflowId);
                                    childWorkflowFormField.setModuleId(moduleDTO.getId());
                                    childWorkflowFormField.setFieldId(childField.getFieldId());
//                                    childWorkflowFormField.setIsRequired(childField.getIsRequired());
                                    childWorkflowFormField.setFieldOrder(childField.getFieldOrder());
                                    childWorkflowFormField.setPlaceholderText(childField.getPlaceholderText());
                                    childWorkflowFormField.setEmptyStateText(childField.getEmptyStateText());
                                    childWorkflowFormField.setIsHidden(childField.getIsHidden());
                                    childWorkflowFormField.setIsEnabled(childField.getIsEnabled() != null ? childField.getIsEnabled() : fieldDTO.getIsEnabled());

                                    if (childField.getHelpContent() != null) {
                                        childWorkflowFormField.setHelpContent(JSON.toJSONString(childField.getHelpContent()));
                                    }
                                    childWorkflowFormField.setHelpDisplayType(childField.getHelpDisplayType());

                                    saveOrUpdateFields.add(childWorkflowFormField);
                                }
                            }
                        }
                    }
                }

                // 查询当前工作流下的所有表单字段
                List<ContractWorkflowFormFieldEntity> existingFields = contractWorkflowFormFieldService.list(
                        new LambdaQueryWrapper<ContractWorkflowFormFieldEntity>()
                                .eq(ContractWorkflowFormFieldEntity::getWorkflowId, workflowId));

                // 找出需要删除的字段（存在于数据库但不在当前提交的数据中）
                List<Long> fieldsToDisable = existingFields.stream()
                        .map(ContractWorkflowFormFieldEntity::getId)
                        .filter(id -> !incomingFieldIds.contains(id))
                        .collect(Collectors.toList());

                // 删除旧字段
                if (!CollectionUtils.isEmpty(fieldsToDisable)) {
                    contractWorkflowFormFieldService.remove(
                            new LambdaQueryWrapper<ContractWorkflowFormFieldEntity>()
                                    .in(ContractWorkflowFormFieldEntity::getId, fieldsToDisable));
                }

                // 保存或更新字段
                if (!CollectionUtils.isEmpty(saveOrUpdateFields)) {
                    contractWorkflowFormFieldService.saveOrUpdateBatch(saveOrUpdateFields);
                }
            }

            // 3. 第三步：保存高级配置信息
            if (workflowSaveDTO.getEmptyState() != null) {
                contractWorkflowEntity.setEmptyState(workflowSaveDTO.getEmptyState());
            }
            if (workflowSaveDTO.getRepeatState() != null) {
                contractWorkflowEntity.setRepeatState(workflowSaveDTO.getRepeatState());
            }
            if (!CollectionUtils.isEmpty(workflowSaveDTO.getUserId())) {
                String userIds = workflowSaveDTO.getUserId().stream()
                        .map(String::valueOf)
                        .collect(Collectors.joining(","));
                contractWorkflowEntity.setUserId(userIds);
            }

            // 处理跳过指定节点的id，将假id替换为真实id
            if (!CollectionUtils.isEmpty(workflowSaveDTO.getNodeId())) {
                String skipNode = workflowSaveDTO.getNodeId().stream().map(String::valueOf).collect(Collectors.joining(","));
                contractWorkflowEntity.setNodeId(skipNode);
            }

            // 设置工作流发布状态为未发布
            if (ObjectUtil.isNotNull(workflowSaveDTO.getAuto()) && workflowSaveDTO.getAuto()) {
                contractWorkflowEntity.setIsPublished(false);
            }

            // 更新工作流基本信息和高级配置
            contractWorkflowService.updateById(contractWorkflowEntity);

            // 记录操作日志
            log.info("保存工作流表单字段描述成功，workflowId: {}, workflowName: {}",
                    workflowId, contractWorkflowEntity.getWorkflowName());
            return SingleResponse.success();
        } catch (Exception e) {
            log.error("保存工作流表单字段描述失败，workflowId: {}, error: {}", workflowId, e.getMessage(), e);
            return SingleResponse.failure(ResponseCodeEnum.BUSINESS_EXCEPTION.getCode(), "保存工作流表单字段描述失败");
        }
    }

    /**
     * 删除合同工作流
     *
     * @param id 工作流ID
     * @return 操作结果
     */
    public SingleResponse<Boolean> deleteContractWorkflow(Integer id) {
        // 参数校验
        if (id == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "工作流ID不能为空");
        }

        // 查询工作流信息
        ContractWorkflowEntity contractWorkflowEntity = contractWorkflowService.getById(id);
        if (contractWorkflowEntity == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "工作流不存在");
        }

        // 检查工作流状态：已启用的工作流不允许直接删除
        if (contractWorkflowEntity.getIsEnabled()) {
            return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "已启用的工作流不能删除，请先停用");
        }

        List<Integer> scope = contractWorkflowTypeService.list(Wrappers.<ContractWorkflowTypeEntity>lambdaQuery()
                        .eq(ContractWorkflowTypeEntity::getWorkflowId, id)
                        .select(ContractWorkflowTypeEntity::getContractTypeId))
                .stream().map(ContractWorkflowTypeEntity::getContractTypeId).toList();

        // 删除工作流类型关联
        contractWorkflowTypeService.remove(new LambdaQueryWrapper<ContractWorkflowTypeEntity>()
                .eq(ContractWorkflowTypeEntity::getWorkflowId, id));


//        contractWorkflowDepartmentService.remove(new LambdaQueryWrapper<ContractWorkflowDepartment>()
//                .eq(ContractWorkflowDepartment::getWorkflowId, id));
//
//        // 删除工作流法人关联
//        contractWorkflowLegalService.remove(Wrappers.<ContractWorkflowLegal>lambdaQuery()
//                .eq(ContractWorkflowLegal::getWorkflowId, id));

        // 删除工作流
        contractWorkflowService.removeById(id);

        // 记录日志
        log.info("工作流删除成功，workflowId: {}, workflowName: {},",
                id, contractWorkflowEntity.getWorkflowName());

        delProcessCache(scope,contractWorkflowEntity.getProcessKey(), contractWorkflowEntity.getPriority());

        return SingleResponse.success();
    }

    private void delProcessCache(List<Integer> scope, String processKey, Integer priority) {
        scope.forEach(contractTypeId -> {
            Integer currentPriority = redisService.getCacheMapValue(RedisKeyConstant.Business.APPROVAL_TYPE_PROCESS_PREFIX + contractTypeId,
                    RedisCacheEnum.ProcessKeyTypeCache.PRIORITY.getValue());
            if (currentPriority == null || currentPriority.equals(priority)) {
                redisService.deleteObject(RedisKeyConstant.Business.APPROVAL_TYPE_PROCESS_PREFIX + contractTypeId);
                // 重新查找优先级最大的工作流
                ProcessKeyTypeCache maxProcessKeyByType = contractWorkflowTypeService.getMaxProcessKeyByType(contractTypeId);
                if (maxProcessKeyByType != null) {
                    redisService.setHashObject(RedisKeyConstant.Business.APPROVAL_TYPE_PROCESS_PREFIX + contractTypeId,maxProcessKeyByType);
                }
            }
        });
    }

    /**
     * 复制合同工作流
     *
     * @param id
     * @param copyWorkflowDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse<WorkflowShowDTO> copyContractWorkflow(Integer id, CopyWorkflowDTO copyWorkflowDTO) {
        // 参数校验
        if (id == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "工作流ID不能为空");
        }
        if (!id.equals(copyWorkflowDTO.getWorkflowId())) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "工作流ID不一致");
        }

        // 查询源工作流信息
        ContractWorkflowEntity contractWorkflowEntity = contractWorkflowService.getById(id);
        if (contractWorkflowEntity == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "工作流不存在");
        }

        FlwProcess flwProcess = flwProcessMapper.selectById(copyWorkflowDTO.getProcessId());
        if (null == flwProcess) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "流程定义不存在");
        }

        // 验证合同类型范围的租户权限
        String[] typeIds = copyWorkflowDTO.getScope().split(",");
        List<Integer> contractTypeIds = Arrays.stream(typeIds)
                .map(Integer::parseInt)
                .collect(Collectors.toList());

        List<ContractTypeEntity> contractTypes = contractTypeService.listByIds(contractTypeIds);
        if (contractTypes.size() != contractTypeIds.size()) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "部分合同类型不存在");
        }

        // 检查工作流名称重复
        long count = contractWorkflowService.count(new LambdaQueryWrapper<ContractWorkflowEntity>()
                .eq(ContractWorkflowEntity::getWorkflowName, copyWorkflowDTO.getWorkflowName()));
        if (count > 0) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "工作流名称重复");
        }

        try {
            // 第一步：先同步保存工作流主表，确保获得主键ID
            ContractWorkflowEntity newWorkflow = new ContractWorkflowEntity();
            BeanUtils.copyProperties(contractWorkflowEntity, newWorkflow);
            newWorkflow.setId(null);
            newWorkflow.setWorkflowName(copyWorkflowDTO.getWorkflowName());
            newWorkflow.setIsPublished(false);
            newWorkflow.setCreatedAt(new Date());
            newWorkflow.setUpdatedAt(new Date());
            newWorkflow.setProcessKey(flwProcess.getProcessKey());
            newWorkflow.setPriority(copyWorkflowDTO.getPriority());
            contractWorkflowService.save(newWorkflow);

            log.info("工作流主表保存成功，workflowId: {}", newWorkflow.getId());

            // 第二步：并行执行相关数据复制，这些操作可以并行进行

            // 复制工作流类型关联
            List<ContractWorkflowTypeEntity> types = Arrays.stream(copyWorkflowDTO.getScope().split(","))
                    .map(Integer::valueOf)
                    .map(typeId -> {
                        ContractWorkflowTypeEntity contractWorkflowTypeEntity = new ContractWorkflowTypeEntity();
                        contractWorkflowTypeEntity.setWorkflowId(newWorkflow.getId());
                        contractWorkflowTypeEntity.setContractTypeId(typeId);
                        return contractWorkflowTypeEntity;
                    }).collect(Collectors.toList());
            contractWorkflowTypeService.saveBatch(types);
            log.info("工作流类型关联复制完成，workflowId: {}", newWorkflow.getId());

            // 复制部门关联
            List<ContractWorkflowDepartment> collect = copyWorkflowDTO.getDepartment().stream().map(item -> {
                ContractWorkflowDepartment department = new ContractWorkflowDepartment();
                department.setWorkflowId(newWorkflow.getId());
                department.setDepartmentId(item);
                return department;
            }).collect(Collectors.toList());
            contractWorkflowDepartmentService.saveBatch(collect);

            // 第四步：等待所有操作完成

            // 记录日志
            log.info("工作流复制成功，源工作流ID: {}, 源工作流名称: {}, 新工作流ID: {}, 新工作流名称: {}",
                    id, contractWorkflowEntity.getWorkflowName(), newWorkflow.getId(),
                    copyWorkflowDTO.getWorkflowName());

//            return SingleResponse.of(initWorkflowShowDTO(newWorkflow.getId()));
            return SingleResponse.success();
        } catch (Exception e) {
            log.error("工作流复制失败，源工作流ID: {}, 错误信息: {}", id, e.getMessage(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return SingleResponse.failure(ResponseCodeEnum.BUSINESS_EXCEPTION.getCode(), "工作流复制失败");
        }
    }

    /**
     * 获取合同工作流表单字段
     *
     * @param workflowId
     * @return
     */
    public SingleResponse<List<WorkflowFormFieldsListDTO>> listWorkflowFormFields(Long workflowId) {
        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (Objects.isNull(currentUser.getEmployeeId())) {
            return SingleResponse.failure(ResponseCodeEnum.NOT_LOGGED.getCode(), ResponseCodeEnum.NOT_LOGGED.getMsg());
        }
        // 参数校验
//        if (workflowId == null) {
//            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "工作流ID不能为空");
//        }
//
//        // 查询工作流信息
//        ContractWorkflowEntity contractWorkflowEntity = contractWorkflowService.getById(workflowId);
//        if (contractWorkflowEntity == null) {
//            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "工作流不存在");
//        }
//        if (!contractWorkflowEntity.getIsEnabled()) {
//            return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "工作流已禁用");
//        }

        // 获取所有启用的模块
        List<ContractModuleEntity> allModules = contractModuleService.list(new LambdaQueryWrapper<ContractModuleEntity>()
                .eq(ContractModuleEntity::getIsEnabled, true)
                .orderByAsc(ContractModuleEntity::getModuleOrder));

        if (CollectionUtils.isEmpty(allModules)) {
            return SingleResponse.of(new ArrayList<>());
        }

        // 查询流程关联的模块
        List<ContractWorkflowModuleEntity> workflowModules = contractWorkflowModuleService.list(
                new LambdaQueryWrapper<ContractWorkflowModuleEntity>()
                        .eq(ContractWorkflowModuleEntity::getWorkflowId, workflowId)
        );
        List<Integer> associatedModuleIds = workflowModules.stream()
                .map(ContractWorkflowModuleEntity::getModuleId)
                .collect(Collectors.toList());

        // 获取工作流表单字段
        // is_hidden=0(不隐藏)，is_enabled=1(可用)，is_deleted=0(未删除)
        List<ContractWorkflowFormFieldEntity> workflowFormFields = contractWorkflowFormFieldService.list(
                new LambdaQueryWrapper<ContractWorkflowFormFieldEntity>()
                        .eq(ContractWorkflowFormFieldEntity::getWorkflowId, workflowId)
                        .eq(ContractWorkflowFormFieldEntity::getIsHidden, false)
                        .eq(ContractWorkflowFormFieldEntity::getIsEnabled, true)
                        .eq(ContractWorkflowFormFieldEntity::getIsDeleted, false));

        // 构建字段ID和模块ID到工作流表单字段的映射
        Map<String, ContractWorkflowFormFieldEntity> workflowFormFieldMap = workflowFormFields.stream()
                .collect(Collectors.toMap(
                        field -> field.getFieldId() + "_" + field.getModuleId(),
                        field -> field
                ));

        // 获取所有启用的模块
        List<Integer> moduleIds = workflowFormFields.stream()
                .map(ContractWorkflowFormFieldEntity::getModuleId)
                .distinct()
                .collect(Collectors.toList());

        // 获取所有模块下的字段
        List<ContractModuleFieldEntity> allModuleFields = contractModuleFieldService.list(
                new LambdaQueryWrapper<ContractModuleFieldEntity>()
                        .in(ContractModuleFieldEntity::getModuleId, allModules.stream()
                                .map(ContractModuleEntity::getId)
                                .collect(Collectors.toList())));

        // 获取所有字段ID
        List<Long> allFieldIds = allModuleFields.stream()
                .map(ContractModuleFieldEntity::getFieldId)
                .distinct()
                .collect(Collectors.toList());

        // 获取字段详细信息
        List<ContractFieldEntity> allFields = contractFieldService.listByIds(allFieldIds).stream()
                .filter(field -> field.getIsEnabled())
                .collect(Collectors.toList());

        // 构建字段ID到字段信息的映射
        Map<Long, ContractFieldEntity> fieldMap = allFields.stream()
                .collect(Collectors.toMap(ContractFieldEntity::getId, field -> field));

        // 分离父字段和子字段
        Map<Long, List<ContractFieldEntity>> parentChildMap = allFields.stream()
                .filter(field -> field.getParentFieldId() != null)
                .collect(Collectors.groupingBy(ContractFieldEntity::getParentFieldId));

        // 构建返回结果
        List<WorkflowFormFieldsListDTO> result = new ArrayList<>();
        for (ContractModuleEntity module : allModules) {
            WorkflowFormFieldsListDTO moduleDTO = new WorkflowFormFieldsListDTO();
            moduleDTO.setId(module.getId());
            moduleDTO.setModuleName(module.getModuleName());
            moduleDTO.setModuleOrder(module.getModuleOrder());
            moduleDTO.setIsSystem(module.getIsSystem());
            moduleDTO.setIsEnabled(module.getIsSystem() || associatedModuleIds.contains(module.getId()));

            // 获取该模块下的所有字段
            List<ContractFieldEntity> moduleFields = allFields.stream()
                    .filter(field -> allModuleFields.stream()
                            .anyMatch(mf -> mf.getModuleId().equals(module.getId()) && mf.getFieldId().equals(field.getId())))
                    .collect(Collectors.toList());

            // 获取所有父字段
            List<ContractFieldEntity> parentFields = moduleFields.stream()
                    .filter(field -> field.getParentFieldId() == null)
                    .collect(Collectors.toList());

            // 构建结果
            List<WorkflowFormFieldDTO> formFields = new ArrayList<>();
            for (ContractFieldEntity parentField : parentFields) {
                String parentKey = parentField.getId() + "_" + module.getId();
                WorkflowFormFieldDTO parentDTO = convertToFormFieldDTO(parentField, workflowFormFieldMap.get(parentKey));

                // 添加子字段
                List<ContractFieldEntity> children = parentChildMap.getOrDefault(parentField.getId(), new ArrayList<>());
                if (!CollectionUtils.isEmpty(children)) {
                    List<WorkflowFormFieldDTO> childDTOs = children.stream()
                            .filter(child -> allModuleFields.stream()
                                    .anyMatch(mf -> mf.getModuleId().equals(module.getId()) && mf.getFieldId().equals(child.getId())))
                            .map(child -> {
                                String childKey = child.getId() + "_" + module.getId();
                                return convertToFormFieldDTO(child, workflowFormFieldMap.get(childKey));
                            })
                            .collect(Collectors.toList());
                    parentDTO.setChildFields(childDTOs);
                }

                formFields.add(parentDTO);
            }

            moduleDTO.setWorkflowFormFields(formFields);
            result.add(moduleDTO);
        }

        return SingleResponse.of(result);
    }

    /**
     * 将ContractField和ContractWorkflowFormField转换为WorkflowFormFieldDTO
     *
     * @param field
     * @param formField
     * @return
     */
    private WorkflowFormFieldDTO convertToFormFieldDTO(ContractFieldEntity field, ContractWorkflowFormFieldEntity formField) {
        WorkflowFormFieldDTO dto = new WorkflowFormFieldDTO();
        BeanUtils.copyProperties(field, dto);
        dto.setFieldOptionsMap(JSON.parseObject(field.getFieldOptions(), Map.class));
        dto.setFieldId(field.getId());
        dto.setId(null);
//        dto.setIsRequired(field.getIsRequired());
        dto.setIsEnabled(false);

        if (formField != null) {
            BeanUtils.copyProperties(formField, dto);
            dto.setHelpContent(JSON.parseObject(formField.getHelpContent(), Map.class));
        }

        return dto;
    }

    /**
     * 发布合同工作流
     *
     * @param workflowId      工作流ID
     * @param workflowSaveDTO
     * @return 操作结果
     */
    public SingleResponse publishContractWorkflow(Long workflowId, WorkflowSaveDTO workflowSaveDTO) {
        // 保存工作流配置
        SingleResponse<Map<Integer, Integer>> saveWorkflowResponse = saveWorkflow(workflowId, workflowSaveDTO);
        if (!saveWorkflowResponse.isSuccess()) {
            return SingleResponse.failure(saveWorkflowResponse.getCode(), null);
        }

        // 添加合同类型校验：相同合同类型只能有一个已发布的工作流
        // 获取当前工作流关联的合同类型
        List<Integer> currentContractTypeIds = contractWorkflowTypeService.list(
                        new LambdaQueryWrapper<ContractWorkflowTypeEntity>()
                                .eq(ContractWorkflowTypeEntity::getWorkflowId, workflowId))
                .stream()
                .map(ContractWorkflowTypeEntity::getContractTypeId)
                .collect(Collectors.toList());

        if (!CollectionUtils.isEmpty(currentContractTypeIds)) {
            // 查询其他已启用工作流中是否有使用相同合同类型的
            List<ContractWorkflowTypeEntity> conflictRelations = contractWorkflowTypeService.list(
                    new LambdaQueryWrapper<ContractWorkflowTypeEntity>()
                            .ne(ContractWorkflowTypeEntity::getWorkflowId, workflowId)
                            .in(ContractWorkflowTypeEntity::getContractTypeId, currentContractTypeIds));

            if (!CollectionUtils.isEmpty(conflictRelations)) {
                // 获取这些工作流，筛选出已启用的
                List<Long> conflictWorkflowIds = conflictRelations.stream()
                        .map(ContractWorkflowTypeEntity::getWorkflowId)
                        .distinct()
                        .collect(Collectors.toList());

                long enabledConflictCount = contractWorkflowService.count(
                        new LambdaQueryWrapper<ContractWorkflowEntity>()
                                .in(ContractWorkflowEntity::getId, conflictWorkflowIds)
                                .eq(ContractWorkflowEntity::getIsEnabled, true));

                if (enabledConflictCount > 0) {
                    // 存在已启用的工作流，不允许发布
                    return SingleResponse.failure(ResponseCodeEnum.OPERATION_NOT_ALLOWED.getCode(), "存在已启用工作流，不允许发布");
                }
            }
        }

        // todo 激活流程实例

        // isPublished字段已废弃，不再需要设置

        return SingleResponse.success();
    }


    // ======================= 获取合同相关选项 =======================


    /**
     * 获取字段类型
     *
     * @return
     */
    public SingleResponse getFieldType() {
        FieldTypeEnum[] values = FieldTypeEnum.values();
        List<FieldTypeEnum> list = Arrays.asList(values);
        List<HashMap<String, String>> collect = list.stream().map(fieldTypeEnum -> {
            HashMap<String, String> stringStringHashMap = new HashMap<>();
            stringStringHashMap.put("key", fieldTypeEnum.getKey());
            stringStringHashMap.put("value", fieldTypeEnum.getValue());
            return stringStringHashMap;
        }).collect(Collectors.toList());
        return SingleResponse.of(collect);
    }

    /**
     * 获取币种
     *
     * @return
     */
    public SingleResponse getCurrency() {
        List<CurrencyEnum> list = Arrays.asList(CurrencyEnum.values());
        List<HashMap<String, String>> collect = list.stream().map(currencyEnum -> {
            HashMap<String, String> stringStringHashMap = new HashMap<>();
            stringStringHashMap.put("currencyId", currencyEnum.getCurrencyId().toString());
            stringStringHashMap.put("name", currencyEnum.getName());
            stringStringHashMap.put("symbol", currencyEnum.getSymbol());
            stringStringHashMap.put("abbreviate", currencyEnum.getAbbreviate());
            return stringStringHashMap;
        }).collect(Collectors.toList());
        return SingleResponse.of(collect);
    }

    public SingleResponse getEmptyAssignee() {
        List<EmptyAssigneeEnum> list = Arrays.asList(EmptyAssigneeEnum.values());
        List<Map<String, String>> collect = list.stream().map(item -> {
            Map<String, String> map = new HashMap<>();
            map.put("key", item.getCode());
            map.put("value", item.getMsg());
            return map;
        }).collect(Collectors.toList());
        return SingleResponse.of(collect);
    }

    public SingleResponse getSelfApproval() {
        List<SelfApprovalEnum> list = Arrays.asList(SelfApprovalEnum.values());
        List<Map<String, String>> collect = list.stream().map(item -> {
            Map<String, String> map = new HashMap<>();
            map.put("key", item.getCode());
            map.put("value", item.getMsg());
            return map;
        }).collect(Collectors.toList());
        return SingleResponse.of(collect);
    }

    public SingleResponse getMonitorLogType() {
        List<LogTypeEnum> list = Arrays.asList(LogTypeEnum.values());
        List<Map<String, String>> collect = list.stream().map(item -> {
            Map<String, String> map = new HashMap<>();
            map.put("key", item.getCode());
            map.put("value", item.getMsg());
            return map;
        }).collect(Collectors.toList());
        return SingleResponse.of(collect);
    }

    /**
     * 获取合同类型树
     *
     * @return
     */
    public SingleResponse<List<ContractTypeTree>> getContractTypeTree() {
        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (Objects.isNull(currentUser.getEmployeeId())) {
            return SingleResponse.failure(ResponseCodeEnum.NOT_LOGGED.getCode(), ResponseCodeEnum.NOT_LOGGED.getMsg());
        }
        List<ContractTypeEntity> firstList = contractTypeService.list(new LambdaQueryWrapper<ContractTypeEntity>()
                .isNull(ContractTypeEntity::getParentId));
        if (CollectionUtils.isEmpty(firstList)) {
            return SingleResponse.of(new ArrayList<>());
        }
        List<Integer> collect = firstList.stream().map(ContractTypeEntity::getId).collect(Collectors.toList());
        Map<Integer, List<ContractTypeTree>> secondMap = contractTypeService.list(new LambdaQueryWrapper<ContractTypeEntity>()
                        .in(ContractTypeEntity::getParentId, collect))
                .stream().map(item -> {
                    ContractTypeTree contractTypeTree = new ContractTypeTree();
                    contractTypeTree.setId(item.getId());
                    contractTypeTree.setName(item.getTypeName());
                    contractTypeTree.setParentId(item.getParentId());
                    return contractTypeTree;
                }).collect(Collectors.groupingBy(ContractTypeTree::getParentId));
        List<ContractTypeTree> result = firstList.stream().map(item -> {
            ContractTypeTree contractTypeTree = new ContractTypeTree();
            contractTypeTree.setId(item.getId());
            contractTypeTree.setName(item.getTypeName());
            contractTypeTree.setParentId(item.getParentId());
            if (secondMap.containsKey(item.getId())) {
                contractTypeTree.setChildren(secondMap.getOrDefault(item.getId(), new ArrayList<>()));
            }
            return contractTypeTree;
        }).collect(Collectors.toList());
        return SingleResponse.of(result);
    }

    /**
     * 获取合同工作流详情
     *
     * @param id 工作流ID
     * @return 工作流详情信息
     */
    public SingleResponse<WorkflowShowDTO> getDetail(Integer id) {
        // 参数校验
        if (id == null) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "工作流ID不能为空");
        }

        // 查询工作流基本信息
        ContractWorkflowEntity workflow = contractWorkflowService.getById(id);
        if (workflow == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "工作流不存在");
        }

        try {
            // 构建工作流详情信息
            WorkflowShowDTO workflowShowDTO = this.buildWorkflowShowDTO(workflow);

            // 记录访问日志
            log.info("获取工作流详情成功，workflowId: {}, workflowName: {}",
                    id, workflow.getWorkflowName());

            return SingleResponse.of(workflowShowDTO);
        } catch (Exception e) {
            log.error("获取工作流详情失败，workflowId: {}, error: {}", id, e.getMessage(), e);
            return SingleResponse.failure(ResponseCodeEnum.BUSINESS_EXCEPTION.getCode(), "获取工作流详情失败");
        }
    }

    /**
     * 赋值展示工作流信息（重构版本，避免重复查询）
     *
     * @param workflow 工作流实体对象
     * @return 工作流展示信息
     */
    private WorkflowShowDTO buildWorkflowShowDTO(ContractWorkflowEntity workflow) {
        WorkflowShowDTO workflowShowDTO = new WorkflowShowDTO();
        Long workflowId = workflow.getId();
        workflowShowDTO.setId(workflowId);
        workflowShowDTO.setWorkflowName(workflow.getWorkflowName());
        workflowShowDTO.setEmptyState(workflow.getEmptyState());
        workflowShowDTO.setRepeatState(workflow.getRepeatState());
        workflowShowDTO.setProcessKey(workflow.getProcessKey());
        workflowShowDTO.setPriority(workflow.getPriority());

        //  设置基本工作流信息（同步设置，避免异步任务中的重复查询）
        BeanUtils.copyProperties(workflow, workflowShowDTO);
        if (EmptyAssigneeEnum.SPECIFIC_USER.equals(workflow.getEmptyState())) {
            workflowShowDTO.setUserId(Arrays.stream(workflow.getUserId().split(","))
                    .map(Long::valueOf).collect(Collectors.toList()));
        }
        if (RepeatAssigneeEnum.SPECIFIC_NODE.equals(workflow.getRepeatState())) {
            workflowShowDTO.setNodeId(Arrays.stream(workflow.getNodeId().split(","))
                    .map(Integer::valueOf).collect(Collectors.toList()));
        }

        // 改为同步执行，避免事务隔离问题
        // 获取工作流范围
        List<Integer> scope = contractWorkflowTypeService.list(new LambdaQueryWrapper<ContractWorkflowTypeEntity>()
                        .eq(ContractWorkflowTypeEntity::getWorkflowId, workflowId))
                .stream().map(ContractWorkflowTypeEntity::getContractTypeId)
                .collect(Collectors.toList());
        workflowShowDTO.setScope(scope);

//        List<Long> departmentIds = contractWorkflowDepartmentService.list(new LambdaQueryWrapper<ContractWorkflowDepartment>()
//                        .eq(ContractWorkflowDepartment::getWorkflowId, workflowId))
//                .stream().map(ContractWorkflowDepartment::getDepartmentId).collect(Collectors.toList());
//        workflowShowDTO.setDepartment(departmentIds);
//
//        // 获取法人关联
//        List<Integer> legalIds = contractWorkflowLegalService.list(Wrappers.<ContractWorkflowLegal>lambdaQuery()
//                        .eq(ContractWorkflowLegal::getWorkflowId, workflowId))
//                .stream().map(ContractWorkflowLegal::getLegalId).toList();
//        workflowShowDTO.setLegalIds(legalIds);

        // 查询流程定义
        FlwProcess flwProcess = flwProcessMapper.selectOne(Wrappers.<FlwProcess>lambdaQuery()
                .eq(FlwProcess::getProcessKey, workflow.getProcessKey())
                .orderByDesc(FlwProcess::getProcessVersion)
                .last("limit 1"));

        workflowShowDTO.setProcessId(flwProcess.getId());
        workflowShowDTO.setProcessName(flwProcess.getProcessName());


        // 返回工作流信息
        return workflowShowDTO;
    }

    /**
     * 赋值展示工作流信息（保留原有方法名以兼容其他调用）
     *
     * @param workflowId 工作流ID
     * @return 工作流展示信息
     */
    public WorkflowShowDTO initWorkflowShowDTO(Long workflowId) {
        // 查询工作流信息
        ContractWorkflowEntity workflow = contractWorkflowService.getById(workflowId);
        if (workflow == null) {
            return new WorkflowShowDTO();
        }

        return buildWorkflowShowDTO(workflow);
    }

    /**
     * 添加流程模块关联
     *
     * @param workflowId        流程ID
     * @param workflowModuleDTO 模块关联请求DTO
     * @return SingleResponse
     */
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse addWorkflowModules(Long workflowId, WorkflowModuleDTO workflowModuleDTO) {
        // 1. 验证流程是否存在
        ContractWorkflowEntity workflow = contractWorkflowService.getById(workflowId);
        if (workflow == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "流程不存在");
        }

        // 2. 验证模块是否存在
        List<ContractModuleEntity> modules = contractModuleService.listByIds(workflowModuleDTO.getModuleIds());
        if (modules.size() != workflowModuleDTO.getModuleIds().size()) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "部分模块不存在");
        }

        // 3. 批量保存关联关系
        List<ContractWorkflowModuleEntity> workflowModules = workflowModuleDTO.getModuleIds().stream()
                .map(moduleId -> {
                    ContractWorkflowModuleEntity entity = new ContractWorkflowModuleEntity();
                    entity.setWorkflowId(workflowId);
                    entity.setModuleId(moduleId);
                    return entity;
                })
                .collect(Collectors.toList());

        contractWorkflowModuleService.saveBatch(workflowModules);
        return SingleResponse.success();
    }

    /**
     * 删除流程模块关联
     *
     * @param workflowId        流程ID
     * @param workflowModuleDTO 模块关联请求DTO
     * @return SingleResponse
     */
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse deleteWorkflowModules(Long workflowId, WorkflowModuleDTO workflowModuleDTO) {
        // 1. 验证流程是否存在
        ContractWorkflowEntity workflow = contractWorkflowService.getById(workflowId);
        if (workflow == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "流程不存在");
        }

        // 2. 删除关联关系
        contractWorkflowModuleService.remove(
                new LambdaQueryWrapper<ContractWorkflowModuleEntity>()
                        .eq(ContractWorkflowModuleEntity::getWorkflowId, workflowId)
                        .in(ContractWorkflowModuleEntity::getModuleId, workflowModuleDTO.getModuleIds())
        );

        return SingleResponse.success();
    }

    /**
     * 获取所有模块的字段树
     *
     * @return 模块字段树列表
     */
    public SingleResponse<List<ModuleFieldTreeDTO>> getAllModuleFieldTree() {
        try {
            // 获取所有模块
            List<ContractModuleEntity> modules = contractModuleMapper.selectList(
                    new QueryWrapper<ContractModuleEntity>()
                            .orderByAsc("module_order")
            );

            if (CollectionUtils.isEmpty(modules)) {
                return SingleResponse.of(new ArrayList<>());
            }

            // 获取所有字段
            List<ContractFieldEntity> allFields = contractFieldMapper.selectAllFields();
            if (CollectionUtils.isEmpty(allFields)) {
                return SingleResponse.of(new ArrayList<>());
            }

            // 构建字段树 - 先过滤掉没有模块关联的字段，再分组
            Map<Integer, List<ContractFieldEntity>> moduleFieldsMap = allFields.stream()
                    .filter(field -> {
                        ContractModuleFieldEntity moduleField = contractModuleFieldMapper.selectByFieldId(field.getId());
                        return moduleField != null && moduleField.getModuleId() != null;
                    })
                    .collect(Collectors.groupingBy(field -> {
                        ContractModuleFieldEntity moduleField = contractModuleFieldMapper.selectByFieldId(field.getId());
                        return moduleField.getModuleId(); // 这里不会为null，因为上面已经过滤了
                    }));

            // 构建返回结果
            List<ModuleFieldTreeDTO> result = new ArrayList<>();
            for (ContractModuleEntity module : modules) {
                ModuleFieldTreeDTO moduleTree = new ModuleFieldTreeDTO();
                moduleTree.setModuleId(module.getId());
                moduleTree.setModuleName(module.getModuleName());
                moduleTree.setModuleDescription(module.getModuleDescription());
                moduleTree.setModuleOrder(module.getModuleOrder());

                List<ContractFieldEntity> moduleFields = moduleFieldsMap.getOrDefault(module.getId(), new ArrayList<>());
                if (!CollectionUtils.isEmpty(moduleFields)) {
                    // 分离父字段和子字段
                    Map<Integer, List<ContractFieldEntity>> parentChildMap = moduleFields.stream()
                            .filter(field -> field.getParentFieldId() != null)
                            .collect(Collectors.groupingBy(field -> field.getParentFieldId().intValue()));

                    // 获取所有父字段（不再按field_order排序）
                    List<ContractFieldEntity> parentFields = moduleFields.stream()
                            .filter(field -> field.getParentFieldId() == null)
                            .collect(Collectors.toList());

                    List<ContractFieldShowDTO> fieldTree = new ArrayList<>();
                    for (ContractFieldEntity parentField : parentFields) {
                        ContractFieldShowDTO parentDto = convertToContractFieldShowDTO(parentField);

                        // 如果是GROUP类型，添加子字段
                        if ("GROUP".equals(parentField.getFieldType())) {
                            List<ContractFieldEntity> children = parentChildMap.getOrDefault(parentField.getId().intValue(), new ArrayList<>());
                            if (!CollectionUtils.isEmpty(children)) {
                                List<ContractFieldShowDTO> childDtos = children.stream()
                                        .map(this::convertToContractFieldShowDTO)
                                        .collect(Collectors.toList());
                                parentDto.setChildren(childDtos);
                            }
                        }
                        fieldTree.add(parentDto);
                    }
                    moduleTree.setFields(fieldTree);
                }
                result.add(moduleTree);
            }

            return SingleResponse.of(result);
        } catch (Exception e) {
            log.error("获取所有模块的字段树失败", e);
            return SingleResponse.failure(ResponseCodeEnum.SHOW_MSG.getCode(), "获取字段树失败: " + e.getMessage());
        }
    }

    /**
     * 转换ContractFieldEntity到ContractFieldShowDTO，处理fieldOptions的JSON转换
     *
     * @param fieldEntity 字段实体
     * @return 字段显示DTO
     */
    private ContractFieldShowDTO convertToContractFieldShowDTO(ContractFieldEntity fieldEntity) {
        ContractFieldShowDTO dto = new ContractFieldShowDTO();

        // 手动设置字段，处理类型转换（Long -> Integer）
        dto.setId(fieldEntity.getId() != null ? fieldEntity.getId() : null);
        dto.setParentFieldId(fieldEntity.getParentFieldId() != null ? fieldEntity.getParentFieldId() : null);
        dto.setFieldName(fieldEntity.getFieldName());
        dto.setCode(fieldEntity.getCode());
        dto.setFieldType(fieldEntity.getFieldType());
        dto.setIsRequired(fieldEntity.getIsRequired());
        dto.setIsEnabled(fieldEntity.getIsEnabled());
        dto.setIsSystem(fieldEntity.getIsSystem());

        // 处理fieldOptions的JSON转换
        if (fieldEntity.getFieldOptions() != null && !fieldEntity.getFieldOptions().trim().isEmpty()) {
            try {
                // 将JSON字符串转换为Map
                Map<String, Object> fieldOptionsMap = JSONObject.parseObject(fieldEntity.getFieldOptions(), Map.class);
                dto.setFieldOptions(fieldOptionsMap);
            } catch (Exception e) {
                log.warn("转换字段选项JSON失败，字段ID: {}, fieldOptions: {}", fieldEntity.getId(), fieldEntity.getFieldOptions(), e);
                // 如果JSON解析失败，设置为null
                dto.setFieldOptions(null);
            }
        }

        // 设置模块字段关联信息
        ContractModuleFieldEntity moduleField = contractModuleFieldMapper.selectByFieldId(fieldEntity.getId());
        if (moduleField != null) {
            dto.setFieldOrder(moduleField.getFieldOrder());
            dto.setModuleId(moduleField.getModuleId());
        }

        return dto;
    }

    /**
     * 根据权限获取全部合同类型（层级结构）
     * 支持部门权限和用户权限的并集，满足任意一种权限都可以展示
     *
     * @return 合同类型层级结构列表（一级类型包含其下所有子类型）
     */
    public SingleResponse<List<ContractTypeEntity>> getAllContractTypesByPermission() {
        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (Objects.isNull(currentUser.getEmployeeId())) {
            return SingleResponse.failure(ResponseCodeEnum.NOT_LOGGED.getCode(), ResponseCodeEnum.NOT_LOGGED.getMsg());
        }

        // 获取当前用户的主部门ID（可能为空）
        Long mainDepartmentId = sysUserDepartmentService.getMainDepartmentIdByUserId(currentUser.getId());

        // 按部门授权：查询当前部门可用的合同类型ID列表
        Set<Integer> allowedTypeIds = new HashSet<>();
        if (mainDepartmentId != null) {
            List<ContractTypeDepartmentEntity> typeDepartments = contractTypeDepartmentService.list(
                    new LambdaQueryWrapper<ContractTypeDepartmentEntity>()
                            .eq(ContractTypeDepartmentEntity::getDepartmentId, mainDepartmentId)
            );
            allowedTypeIds.addAll(typeDepartments.stream()
                    .map(ContractTypeDepartmentEntity::getContractTypeId)
                    .collect(Collectors.toSet()));
        }

        // 按人员授权：查询当前用户可用的合同类型ID列表
        List<ContractTypeUser> typeUsersForCurrent = contractTypeUserService.list(
                new LambdaQueryWrapper<ContractTypeUser>()
                        .eq(ContractTypeUser::getUserId, currentUser.getId())
        );
        allowedTypeIds.addAll(typeUsersForCurrent.stream()
                .map(ContractTypeUser::getContractTypeId)
                .collect(Collectors.toSet()));

        if (allowedTypeIds.isEmpty()) {
            return SingleResponse.of(new ArrayList<>());
        }

        // 查询启用的合同类型并按权限过滤
        List<ContractTypeEntity> allContractTypes = contractTypeService.list(
                new LambdaQueryWrapper<ContractTypeEntity>()
                        .eq(ContractTypeEntity::getIsEnabled, true)
                        .in(ContractTypeEntity::getId, allowedTypeIds)
                        .orderByAsc(ContractTypeEntity::getTypeOrder)
        );

        if (CollectionUtils.isEmpty(allContractTypes)) {
            return SingleResponse.of(new ArrayList<>());
        }

        // 构建层级结构：一级类型包含其下的所有子类型
        List<ContractTypeEntity> result = buildContractTypeHierarchyStructure(allContractTypes);

        return SingleResponse.of(result);
    }

    /**
     * 构建合同类型层级名称数组
     *
     * @param contractTypeId 合同类型ID
     * @return 层级名称数组，从一级到当前级别
     */
    private String[] buildContractTypeHierarchy(Integer contractTypeId) {
        if (contractTypeId == null) {
            return new String[0];
        }

        List<String> typeNames = new ArrayList<>();
        ContractTypeEntity currentType = contractTypeService.getById(contractTypeId);

        // 递归查找所有父级类型
        while (currentType != null) {
            typeNames.add(0, currentType.getTypeName()); // 在列表开头插入

            if (currentType.getParentId() != null) {
                currentType = contractTypeService.getById(currentType.getParentId());
            } else {
                break;
            }
        }

        return typeNames.toArray(new String[0]);
    }

    /**
     * 构建合同类型层级结构（一级类型包含其下所有子类型）
     *
     * @param allContractTypes 所有合同类型列表
     * @return 层级结构列表
     */
    private List<ContractTypeEntity> buildContractTypeHierarchyStructure(List<ContractTypeEntity> allContractTypes) {
        if (CollectionUtils.isEmpty(allContractTypes)) {
            return new ArrayList<>();
        }

        // 创建ID到实体的映射，便于查找
        Map<Integer, ContractTypeEntity> typeMap = allContractTypes.stream()
                .collect(Collectors.toMap(ContractTypeEntity::getId, type -> type));

        // 找到所有一级类型（parentId为null）
        List<ContractTypeEntity> firstLevelTypes = allContractTypes.stream()
                .filter(type -> type.getParentId() == null)
                .sorted(Comparator.comparing(ContractTypeEntity::getTypeOrder))
                .collect(Collectors.toList());

        // 为每个一级类型构建完整的子类型层级
        for (ContractTypeEntity firstLevel : firstLevelTypes) {
            List<ContractTypeEntity> children = buildChildrenHierarchy(firstLevel.getId(), typeMap);
            firstLevel.setChildren(children);
        }

        return firstLevelTypes;
    }

    /**
     * 递归构建子类型层级
     *
     * @param parentId 父类型ID
     * @param typeMap  类型映射
     * @return 子类型列表
     */
    private List<ContractTypeEntity> buildChildrenHierarchy(Integer parentId, Map<Integer, ContractTypeEntity> typeMap) {
        List<ContractTypeEntity> children = new ArrayList<>();

        for (ContractTypeEntity type : typeMap.values()) {
            if (Objects.equals(type.getParentId(), parentId)) {
                // 为子类型递归构建其子类型
                List<ContractTypeEntity> grandChildren = buildChildrenHierarchy(type.getId(), typeMap);
                type.setChildren(grandChildren);
                children.add(type);
            }
        }

        // 按照typeOrder排序
        children.sort(Comparator.comparing(ContractTypeEntity::getTypeOrder));

        return children;
    }

    /**
     * 根据合同类型名称模糊搜索合同类型
     *
     * @param typeName 合同类型名称（模糊搜索）
     * @return 合同类型列表（层级结构）
     */
    public SingleResponse<List<ContractTypeShowDTO>> searchContractTypesByName(String typeName) {
        // 参数校验
        if (StringUtils.isEmpty(typeName)) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), "搜索关键词不能为空");
        }

        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (Objects.isNull(currentUser.getEmployeeId())) {
            return SingleResponse.failure(ResponseCodeEnum.NOT_LOGGED.getCode(), ResponseCodeEnum.NOT_LOGGED.getMsg());
        }

        // 获取当前用户的主部门ID（可能为空）
        Long mainDepartmentId = sysUserDepartmentService.getMainDepartmentIdByUserId(currentUser.getId());

        // 按部门授权：查询当前部门可用的合同类型ID列表
        Set<Integer> allowedTypeIds = new HashSet<>();
        if (mainDepartmentId != null) {
            List<ContractTypeDepartmentEntity> typeDepartments = contractTypeDepartmentService.list(
                    new LambdaQueryWrapper<ContractTypeDepartmentEntity>()
                            .eq(ContractTypeDepartmentEntity::getDepartmentId, mainDepartmentId)
            );
            allowedTypeIds.addAll(typeDepartments.stream()
                    .map(ContractTypeDepartmentEntity::getContractTypeId)
                    .collect(Collectors.toSet()));
        }

        // 按人员授权：查询当前用户可用的合同类型ID列表
        List<ContractTypeUser> typeUsersForCurrent = contractTypeUserService.list(
                new LambdaQueryWrapper<ContractTypeUser>()
                        .eq(ContractTypeUser::getUserId, currentUser.getId())
        );
        allowedTypeIds.addAll(typeUsersForCurrent.stream()
                .map(ContractTypeUser::getContractTypeId)
                .collect(Collectors.toSet()));

        if (allowedTypeIds.isEmpty()) {
            return SingleResponse.of(new ArrayList<>());
        }

        // 获取所有部门数据
        Map<Long, String> departmentNames = sysDepartmentService.getAllDepartmentNames();
        if (departmentNames.isEmpty()){
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), ResponseCodeEnum.DATA_NOT_FOUND.getMsg());
        }

        // 模糊搜索匹配的合同类型（加上部门权限过滤）
        List<ContractTypeEntity> matchedTypes = contractTypeService.list(
                new LambdaQueryWrapper<ContractTypeEntity>()
                        .like(ContractTypeEntity::getTypeName, typeName)
                        .eq(ContractTypeEntity::getIsEnabled, true)
                        .in(ContractTypeEntity::getId, allowedTypeIds)
                        .orderByAsc(ContractTypeEntity::getTypeOrder)
        );

        if (CollectionUtils.isEmpty(matchedTypes)) {
            return SingleResponse.of(new ArrayList<>());
        }

        // 获取所有合同类型（用于构建完整层级，也要加上部门权限过滤）
        List<ContractTypeEntity> allTypes = contractTypeService.list(
                new LambdaQueryWrapper<ContractTypeEntity>()
                        .eq(ContractTypeEntity::getIsEnabled, true)
                        .in(ContractTypeEntity::getId, allowedTypeIds)
        );

        // 获取合同类型与部门的关联关系
        List<Integer> allTypeIds = allTypes.stream().map(ContractTypeEntity::getId).collect(Collectors.toList());
        LambdaQueryWrapper<ContractTypeDepartmentEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(ContractTypeDepartmentEntity::getContractTypeId, allTypeIds);
        List<ContractTypeDepartmentEntity> allTypeDepartments = contractTypeDepartmentService.list(wrapper);

        // 构建合同类型与部门的映射关系
        Map<Integer, List<Long>> typeDepartmentMap = allTypeDepartments.stream()
                .collect(Collectors.groupingBy(
                        ContractTypeDepartmentEntity::getContractTypeId,
                        Collectors.mapping(ContractTypeDepartmentEntity::getDepartmentId, Collectors.toList())
                ));

        // 获取合同类型与用户的关联关系（仅限可见集合）
        LambdaQueryWrapper<ContractTypeUser> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.in(ContractTypeUser::getContractTypeId, allTypeIds);
        List<ContractTypeUser> allTypeUsers = contractTypeUserService.list(userWrapper);

        Map<Integer, List<Long>> typeUserMap = allTypeUsers.stream()
                .collect(Collectors.groupingBy(
                        ContractTypeUser::getContractTypeId,
                        Collectors.mapping(ContractTypeUser::getUserId, Collectors.toList())
                ));

        // 预加载用户头像信息
        Map<Long, UserAvatarVO> userAvatarMap = new HashMap<>();
        if (!allTypeUsers.isEmpty()) {
            List<Long> userIds = allTypeUsers.stream()
                    .map(ContractTypeUser::getUserId)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());
            if (!userIds.isEmpty()) {
                List<UserAvatarVO> avatars = sysUserMapper.getUserAvatarsByIds(userIds);
                if (avatars != null) {
                    for (UserAvatarVO avatar : avatars) {
                        if (avatar != null) {
                            userAvatarMap.put(avatar.getUserId(), avatar);
                        }
                    }
                }
            }
        }

        long totalDepartmentCount = sysDepartmentService.count();

        // 构建ID到实体的映射
        Map<Integer, ContractTypeEntity> allTypeMap = allTypes.stream()
                .collect(Collectors.toMap(ContractTypeEntity::getId, type -> type));

        // 分离匹配的一级类型和非一级类型
        List<ContractTypeEntity> matchedFirstLevel = new ArrayList<>();
        List<ContractTypeEntity> matchedNonFirstLevel = new ArrayList<>();

        for (ContractTypeEntity type : matchedTypes) {
            if (type.getParentId() == null) {
                matchedFirstLevel.add(type);
            } else {
                matchedNonFirstLevel.add(type);
            }
        }

        // 记录已经包含在一级类型下的类型ID和已经处理的一级类型ID，用于去重
        Set<Integer> includedTypeIds = new HashSet<>();
        Set<Integer> processedFirstLevelIds = new HashSet<>();

        // 处理匹配的一级类型，获取其完整的子类型层级
        List<ContractTypeShowDTO> result = new ArrayList<>();
        for (ContractTypeEntity firstLevel : matchedFirstLevel) {
            ContractTypeShowDTO firstLevelDTO = getContractTypeDTO(firstLevel, departmentNames, typeDepartmentMap, typeUserMap, userAvatarMap, totalDepartmentCount);

            // 构建完整的子类型层级
            List<ContractTypeShowDTO> children = buildChildrenHierarchyForSearch(
                    firstLevel.getId(), allTypeMap, departmentNames, typeDepartmentMap, typeUserMap, userAvatarMap, totalDepartmentCount);
            firstLevelDTO.setChildren(children);

            result.add(firstLevelDTO);

            // 记录该一级类型下的所有子类型ID和一级类型ID
            collectAllChildTypeIds(firstLevel.getId(), allTypeMap, includedTypeIds);
            processedFirstLevelIds.add(firstLevel.getId());
        }

        // 处理匹配的非一级类型，构建以一级类型为根的结构
        Map<Integer, List<ContractTypeEntity>> firstLevelToMatchedChildren = new HashMap<>();

        for (ContractTypeEntity nonFirstLevel : matchedNonFirstLevel) {
            if (!includedTypeIds.contains(nonFirstLevel.getId())) {
                // 找到该类型的一级父类型
                Integer firstLevelId = findFirstLevelParent(nonFirstLevel, allTypeMap);
                if (firstLevelId != null && !processedFirstLevelIds.contains(firstLevelId)) {
                    // 将匹配的子类型按一级父类型分组（排除已经处理过的一级类型）
                    firstLevelToMatchedChildren.computeIfAbsent(firstLevelId, k -> new ArrayList<>()).add(nonFirstLevel);
                }
            }
        }

        // 为每个有匹配子类型的一级类型创建结果
        for (Map.Entry<Integer, List<ContractTypeEntity>> entry : firstLevelToMatchedChildren.entrySet()) {
            Integer firstLevelId = entry.getKey();
            List<ContractTypeEntity> matchedChildren = entry.getValue();

            ContractTypeEntity firstLevelType = allTypeMap.get(firstLevelId);
            if (firstLevelType != null) {
                ContractTypeShowDTO firstLevelDTO = getContractTypeDTO(firstLevelType, departmentNames, typeDepartmentMap, typeUserMap, userAvatarMap, totalDepartmentCount);

                // 只添加匹配的子类型到children中
                List<ContractTypeShowDTO> children = matchedChildren.stream()
                        .map(child -> getContractTypeDTO(child, departmentNames, typeDepartmentMap, typeUserMap, userAvatarMap, totalDepartmentCount))
                        .sorted(Comparator.comparing(ContractTypeShowDTO::getTypeOrder))
                        .collect(Collectors.toList());
                firstLevelDTO.setChildren(children);

                result.add(firstLevelDTO);
            }
        }

        // 按照typeOrder排序
        result.sort(Comparator.comparing(ContractTypeShowDTO::getTypeOrder));

        return SingleResponse.of(result);
    }

    /**
     * 递归收集指定类型下的所有子类型ID
     *
     * @param parentId     父类型ID
     * @param allTypeMap   所有类型映射
     * @param collectedIds 收集的类型ID集合
     */
    private void collectAllChildTypeIds(Integer parentId, Map<Integer, ContractTypeEntity> allTypeMap, Set<Integer> collectedIds) {
        for (ContractTypeEntity type : allTypeMap.values()) {
            if (Objects.equals(type.getParentId(), parentId)) {
                collectedIds.add(type.getId());
                // 递归收集子类型的子类型
                collectAllChildTypeIds(type.getId(), allTypeMap, collectedIds);
            }
        }
    }

    /**
     * 找到指定类型的一级父类型ID
     *
     * @param type       合同类型
     * @param allTypeMap 所有类型映射
     * @return 一级父类型ID
     */
    private Integer findFirstLevelParent(ContractTypeEntity type, Map<Integer, ContractTypeEntity> allTypeMap) {
        ContractTypeEntity currentType = type;

        // 向上递归查找，直到找到一级类型（parentId为null）
        while (currentType != null) {
            if (currentType.getParentId() == null) {
                // 找到一级类型
                return currentType.getId();
            }
            // 继续向上查找
            currentType = allTypeMap.get(currentType.getParentId());
        }

        return null;
    }

    /**
     * 为搜索结果构建子类型层级
     *
     * @param parentId          父类型ID
     * @param allTypeMap        所有类型映射
     * @param departmentNames   部门名称映射
     * @param typeDepartmentMap 类型部门映射
     * @return 子类型层级列表
     */
    private List<ContractTypeShowDTO> buildChildrenHierarchyForSearch(Integer parentId,
                                                                       Map<Integer, ContractTypeEntity> allTypeMap,
                                                                       Map<Long, String> departmentNames,
                                                                       Map<Integer, List<Long>> typeDepartmentMap,
                                                                       Map<Integer, List<Long>> typeUserMap,
                                                                       Map<Long, UserAvatarVO> userAvatarMap,
                                                                       long allDepartmentCount) {
        List<ContractTypeShowDTO> children = new ArrayList<>();

        // 找到所有直接子类型
        for (ContractTypeEntity type : allTypeMap.values()) {
            if (Objects.equals(type.getParentId(), parentId)) {
                ContractTypeShowDTO childDto = getContractTypeDTO(type, departmentNames, typeDepartmentMap, typeUserMap, userAvatarMap, allDepartmentCount);

                // 递归构建子类型的子类型
                List<ContractTypeShowDTO> grandChildren = buildChildrenHierarchyForSearch(
                        type.getId(), allTypeMap, departmentNames, typeDepartmentMap, typeUserMap, userAvatarMap, allDepartmentCount);
                childDto.setChildren(grandChildren);

                children.add(childDto);
            }
        }

        // 按照typeOrder排序
        children.sort(Comparator.comparing(ContractTypeShowDTO::getTypeOrder));

        return children;
    }

    /**
     * 更新合同流程
     *
     * @param workflowUpdateDTO
     * @return
     */
    public SingleResponse updateWorkflow(WorkflowUpdateDTO workflowUpdateDTO) {
        // 数据校验
        if (null == workflowUpdateDTO || null == workflowUpdateDTO.getWorkflowId()
                || null == workflowUpdateDTO.getWorkflowName()) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), ResponseCodeEnum.PARAMETER_ERROR.getMsg());
        }
        ContractWorkflowEntity workflow = contractWorkflowService.getById(workflowUpdateDTO.getWorkflowId());
        if (null == workflow) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), ResponseCodeEnum.DATA_NOT_FOUND.getMsg());
        }
        FlwProcess flwProcess = flwProcessMapper.selectById(workflowUpdateDTO.getProcessId());
        if (null == flwProcess) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), ResponseCodeEnum.DATA_NOT_FOUND.getMsg());
        }
        long count = contractWorkflowService.count(new LambdaQueryWrapper<ContractWorkflowEntity>()
                .eq(ContractWorkflowEntity::getWorkflowName, workflowUpdateDTO.getWorkflowName())
                .eq(ContractWorkflowEntity::getWorkflowType, workflowUpdateDTO.getWorkflowType())
                .ne(ContractWorkflowEntity::getId, workflowUpdateDTO.getWorkflowId()));
        if (count > 0) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_ALREADY_EXISTS.getCode(), ResponseCodeEnum.DATA_ALREADY_EXISTS.getMsg());
        }
        // 修改主表
        workflow.setWorkflowName(workflowUpdateDTO.getWorkflowName());
        workflow.setWorkflowType(workflowUpdateDTO.getWorkflowType());
        workflow.setProcessKey(flwProcess.getProcessKey());
        workflow.setPriority(workflowUpdateDTO.getPriority());
        workflow.setIsEnabled(true);
        contractWorkflowService.updateById(workflow);
        // 修改合同流程范围
        contractWorkflowTypeService.remove(new LambdaQueryWrapper<ContractWorkflowTypeEntity>()
                .eq(ContractWorkflowTypeEntity::getWorkflowId, workflowUpdateDTO.getWorkflowId()));
        List<ContractWorkflowTypeEntity> typeEntities = workflowUpdateDTO.getScope().stream().map(item -> {
            ContractWorkflowTypeEntity type = new ContractWorkflowTypeEntity();
            type.setWorkflowId(workflowUpdateDTO.getWorkflowId());
            type.setContractTypeId(item);
            return type;
        }).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(typeEntities)) {
            contractWorkflowTypeService.saveBatch(typeEntities);
        }
        // 修改适用部门
//        contractWorkflowDepartmentService.remove(new LambdaQueryWrapper<ContractWorkflowDepartment>()
//                .eq(ContractWorkflowDepartment::getWorkflowId, workflowUpdateDTO.getWorkflowId()));
//        if (!CollectionUtils.isEmpty(workflowUpdateDTO.getDepartment())) {
//            List<ContractWorkflowDepartment> departmentEntities = workflowUpdateDTO.getDepartment().stream().map(item -> {
//                ContractWorkflowDepartment department = new ContractWorkflowDepartment();
//                department.setWorkflowId(workflowUpdateDTO.getWorkflowId());
//                department.setDepartmentId(item);
//                return department;
//            }).collect(Collectors.toList());
//            contractWorkflowDepartmentService.saveBatch(departmentEntities);
//        }
//
//        // 修改使用法人实体
//        contractWorkflowLegalService.remove(Wrappers.<ContractWorkflowLegal>lambdaQuery()
//                .eq(ContractWorkflowLegal::getWorkflowId, workflowUpdateDTO.getWorkflowId()));
//        if (!CollectionUtils.isEmpty(workflowUpdateDTO.getLegalIds())) {
//            List<ContractWorkflowLegal> legals = workflowUpdateDTO.getLegalIds().stream().map(item -> {
//                ContractWorkflowLegal legal = new ContractWorkflowLegal();
//                legal.setWorkflowId(workflowUpdateDTO.getWorkflowId());
//                legal.setLegalId(item);
//                return legal;
//            }).toList();
//            contractWorkflowLegalService.saveBatch(legals);
//        }

        return SingleResponse.success();
    }

    /**
     * 启用/禁用合同流程配置
     *
     * @param workflowId
     * @return
     */
    public SingleResponse<Boolean> updateStatus(Long workflowId) {
        if (null == workflowId) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), ResponseCodeEnum.PARAMETER_ERROR.getMsg());
        }
        ContractWorkflowEntity workflow = contractWorkflowService.getById(workflowId);
        if (null == workflow) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), ResponseCodeEnum.DATA_NOT_FOUND.getMsg());
        }
        workflow.setIsEnabled(!workflow.getIsEnabled());
        return SingleResponse.of(contractWorkflowService.updateById(workflow));
    }

    /**
     * 获取未设置长期合同类型树
     *
     * @return
     */
    public SingleResponse<List<ContractTypeTree>> getLongTermContractTypeTree() {
        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (Objects.isNull(currentUser.getEmployeeId())) {
            return SingleResponse.failure(ResponseCodeEnum.NOT_LOGGED.getCode(), ResponseCodeEnum.NOT_LOGGED.getMsg());
        }

        // 查询所有启用且未设置长期合同的合同类型
        List<ContractTypeEntity> unsetLongTermTypes = contractTypeService.list(
                new LambdaQueryWrapper<ContractTypeEntity>()
                        .eq(ContractTypeEntity::getIsEnabled, true)
                        .and(wrapper -> wrapper.isNull(ContractTypeEntity::getLongTermId)
                                .or().eq(ContractTypeEntity::getLongTermId, 0))
                        .orderByAsc(ContractTypeEntity::getTypeOrder)
        );

        if (CollectionUtils.isEmpty(unsetLongTermTypes)) {
            return SingleResponse.of(new ArrayList<>());
        }

        // 构建树形结构
        List<ContractTypeTree> result = buildLongTermContractTypeTree(unsetLongTermTypes);

        return SingleResponse.of(result);
    }

    /**
     * 构建长期合同类型树形结构
     *
     * @param contractTypes 合同类型列表
     * @return 树形结构列表
     */
    private List<ContractTypeTree> buildLongTermContractTypeTree(List<ContractTypeEntity> contractTypes) {
        if (CollectionUtils.isEmpty(contractTypes)) {
            return new ArrayList<>();
        }

        // 创建ID到实体的映射，便于查找
        Map<Integer, ContractTypeEntity> typeMap = contractTypes.stream()
                .collect(Collectors.toMap(ContractTypeEntity::getId, type -> type));

        // 找到所有一级类型（parentId为null）
        List<ContractTypeEntity> firstLevelTypes = contractTypes.stream()
                .filter(type -> type.getParentId() == null)
                .sorted(Comparator.comparing(ContractTypeEntity::getTypeOrder))
                .collect(Collectors.toList());

        // 构建返回结果
        List<ContractTypeTree> result = new ArrayList<>();
        for (ContractTypeEntity firstLevel : firstLevelTypes) {
            ContractTypeTree firstLevelTree = convertToContractTypeTree(firstLevel);

            // 递归构建子类型层级
            List<ContractTypeTree> children = buildLongTermContractTypeTreeChildren(firstLevel.getId(), typeMap);
            if (!CollectionUtils.isEmpty(children)) {
                firstLevelTree.setChildren(children);
            }

            result.add(firstLevelTree);
        }

        return result;
    }

    /**
     * 递归构建长期合同类型树的子节点
     *
     * @param parentId 父类型ID
     * @param typeMap  类型映射
     * @return 子类型树列表
     */
    private List<ContractTypeTree> buildLongTermContractTypeTreeChildren(Integer parentId, Map<Integer, ContractTypeEntity> typeMap) {
        List<ContractTypeTree> children = new ArrayList<>();

        for (ContractTypeEntity type : typeMap.values()) {
            if (Objects.equals(type.getParentId(), parentId)) {
                ContractTypeTree childTree = convertToContractTypeTree(type);

                // 递归构建该子类型的子类型
                List<ContractTypeTree> grandChildren = buildLongTermContractTypeTreeChildren(type.getId(), typeMap);
                if (!CollectionUtils.isEmpty(grandChildren)) {
                    childTree.setChildren(grandChildren);
                }

                children.add(childTree);
            }
        }

        // 按照typeOrder排序
        children.sort(Comparator.comparing(child -> {
            Integer id = child.getId();
            ContractTypeEntity entity = typeMap.get(id);
            return entity != null ? entity.getTypeOrder() : 0;
        }));

        return children;
    }

    /**
     * 将ContractTypeEntity转换为ContractTypeTree
     *
     * @param entity 合同类型实体
     * @return 合同类型树节点
     */
    private ContractTypeTree convertToContractTypeTree(ContractTypeEntity entity) {
        ContractTypeTree tree = new ContractTypeTree();
        tree.setId(entity.getId());
        tree.setName(entity.getTypeName());
        tree.setParentId(entity.getParentId());
        // children会在构建过程中设置
        return tree;
    }

    /**
     * 根据父节点ID获取部门树形结构
     *
     * @param dto
     * @return
     */
    public SingleResponse<List<DepartmentTreeVO>> getDepartmentTreeByParent(ContractFieldDepartmentDTO dto) {
        if (null == dto) {
            return SingleResponse.failure(ResponseCodeEnum.PARAMETER_ERROR.getCode(), ResponseCodeEnum.PARAMETER_ERROR.getMsg());
        }
        List<Long> limitDepartmentIds = new ArrayList<>();
        List<Long> departmentIds = new ArrayList<>();
        List<Long> parentDepartmentIds = new ArrayList<>();
        if (null != dto.getParentId()) {
            parentDepartmentIds = contractTypeDepartmentService.list(Wrappers.<ContractTypeDepartmentEntity>lambdaQuery()
                            .eq(ContractTypeDepartmentEntity::getContractTypeId, dto.getParentId())
                            .select(ContractTypeDepartmentEntity::getDepartmentId))
                    .stream().map(ContractTypeDepartmentEntity::getDepartmentId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(parentDepartmentIds)) {
                return SingleResponse.of(new ArrayList<>());
            }
        }
        if (StringUtils.hasText(dto.getMessage())) {
            departmentIds = sysDepartmentService.list(Wrappers.<SysDepartment>lambdaQuery()
                            .like(SysDepartment::getName, dto.getMessage())
                            .select(SysDepartment::getId))
                    .stream().map(SysDepartment::getId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(departmentIds)) {
                return SingleResponse.of(new ArrayList<>());
            }
        }
        // 根据条件设置 limitDepartmentIds
        if (!CollectionUtils.isEmpty(departmentIds) && !CollectionUtils.isEmpty(parentDepartmentIds)) {
            // 两者均不为空，取交集
            limitDepartmentIds = departmentIds.stream()
                    .filter(parentDepartmentIds::contains)
                    .collect(Collectors.toList());
        } else if (!CollectionUtils.isEmpty(departmentIds)) {
            // 仅 departmentIds 不为空
            limitDepartmentIds = new ArrayList<>(departmentIds);
        } else if (!CollectionUtils.isEmpty(parentDepartmentIds)) {
            // 仅 parentDepartmentIds 不为空
            limitDepartmentIds = new ArrayList<>(parentDepartmentIds);
        }

        List<DepartmentTreeVO> result = sysDepartmentService.listAllParentDepartments(limitDepartmentIds);
        return SingleResponse.of(result);
    }
}

